Melarang panggilan ke fungsi / kelas yang berubah-ubah dalam kode eksternal

12

Saya pernah mengalami kasus di mana akan sangat berharga untuk membatasi akses ke API perpustakaan eksternal dan kerangka kerja untuk mencegah konsekuensi negatif dalam sistem.

Misalnya, dalam aplikasi SharePoint, mungkin terasa wajar untuk menelepon spList.Items.GetItemById untuk mendapatkan item daftar, bahkan mungkin dalam satu lingkaran, tanpa menyadari bahwa ini dapat menyebabkan masalah kinerja yang sangat besar.

Bisa juga kita perlu melarang penggunaan SmtpClient untuk memaksa semua orang menggunakan kelas kita sendiri untuk mengirim email, untuk memastikan bahwa kita dapat dengan benar mem-proxy dan mengejek semua email saat berada di lingkungan pengujian.

Adakah cara yang andal dan cukup mudah untuk mencapai kendala-kendala ini pada kode eksternal, kecuali dari tempat tertentu tertentu dalam kode kita sendiri? Tidak perlu benar-benar dalam setiap keadaan mencegah akses ke metode / kelas ini, misalnya dengan refleksi atau hanya semacam penonaktifan, itu harus menjadi peringatan keras bahwa mereka tidak boleh digunakan. Lebih disukai memaksa programmer untuk secara aktif mengambil tindakan untuk mengatasi kendala ini jika memungkinkan / diperlukan.

Alex - Hentikan SE
sumber
11
Ini terdengar seperti penegakan bentuk gaya pengkodean yang ekstrem (Dilarang menggunakan panggilan perpustakaan tertentu). Jadi bagi saya itu menimbulkan pertanyaan prasyarat apakah Anda melakukan review kode, atau cek gaya di tempat pertama?
Peter M
3
Apakah Anda berharap untuk menangkap dan memblokir panggilan ini saat runtime atau waktu kompilasi ?
MetaFight
1
Karena Anda menggunakan C #, apakah Anda pernah mendengar tentang StyleCop ? Anda tahu Anda dapat membuat aturan khusus sesuka Anda, bukan?
Machado
10
" Apakah ada cara yang andal dan cukup mudah untuk mencapai batasan ini pada kode eksternal, kecuali dari tempat tertentu tertentu dalam kode kita sendiri? ". Ya: tulis Roslyn Analyzer Anda sendiri untuk melaporkan mengakses API tertentu sebagai kesalahan kompilasi.
David Arno
3
@Machado, StyleCop secara efektif merupakan produk mati. Itu sedang diganti dengan StyleCopAnalyzers, yang dibangun di atas Roslyn. Ini jelas bukan ide yang baik untuk menginvestasikan waktu dalam menulis aturan StyleCop kustom hari ini.
David Arno

Jawaban:

8

Adakah cara yang andal dan cukup mudah untuk mencapai kendala-kendala ini pada kode eksternal, kecuali dari tempat tertentu tertentu dalam kode kita sendiri?

Karena pertanyaannya secara khusus tentang C #, ada solusi berbasis kompiler yang dapat digunakan di sini untuk menegakkan aturan seperti itu: Roslyn Analyzers . Anda bisa menulis analisis Anda sendiri yang melaporkan mengakses API tertentu sebagai kesalahan kompilasi atau peringatan.

Satu set contoh alat analisis, yang menyediakan banyak kode contoh untuk menulis milik Anda sendiri, adalah StyleCop Analyzers , yang merupakan pengganti fitur StyleCop lama untuk C #.

Karena itu, pemeriksaan otomatis semacam itu selalu dapat diselesaikan oleh orang-orang yang bertekad untuk "melanggar aturan". Oleh karena itu pendekatan ini bukan pengganti untuk tinjauan kode seperti yang dibahas dalam jawaban Karl Bielefeldt. Itu dapat membantu dengan ulasan semacam itu, tetapi sebaiknya tidak menggantinya.

David Arno
sumber
Tidak pernah ada niat untuk mengganti yang lain, saya hanya mencari alat khusus untuk kotak alat saya.
Alex - Hentikan SE
25

Anda dapat melakukan hal-hal yang menghabiskan waktu seperti menulis bungkus di sekitar API eksternal yang meninggalkan operasi yang tidak diinginkan, tetapi tidak ada yang mengalahkan pelatihan dan ulasan kode, karena apa pun standar atau tindakan teknis yang Anda lakukan, orang akan menemukan cara kreatif untuk mengatasinya .

Sebagai contoh, kami memiliki beberapa layanan yang ditulis dalam Scala, dan salah satu hal yang kami tanyakan pada saat tinjauan kode adalah untuk ketidakberdayaan, tetapi kami sering mengomunikasikannya sebagai menyingkirkan vars. Beberapa hari yang lalu menggunakan val x: ListBuffer [Boolean] untuk memegang variabel tunggal yang dapat berubah sebagai satu-satunya item dalam daftar. Anda tidak dapat menugaskan orang lain ListBufferuntuk x, tetapi Anda dapat mengganti item daftar di tempat sebanyak yang Anda inginkan. Seburuk menggunakanvar , tetapi sneakier.

Dengan kata lain, Anda harus memeriksa apakah orang mencari solusi teknis Anda. Jika solusi teknis itu mahal dan menambah kerumitan, Anda sebaiknya mengeceknya dengan benar.

Karl Bielefeldt
sumber
sial itu licik!
whn
@snb Ini setara dengan apa yang dilakukan Java sebagai peretasan untuk berkeliling hanya bisa mengembalikan satu objek / nilai dan tidak memiliki argumen referensi yang tepat; alih-alih melewatkan array yang akan memperbarui isinya. (Beberapa contoh: AtomicMarkableReference.getdan AtomicStampedReference.get).
JAB
Terima kasih atas jawaban Anda, tetapi saya jelas tidak tertarik melakukan hal-hal rumit yang menghabiskan waktu seperti menulis pembungkus di sekitar kode eksternal. Itu bahkan mungkin tidak membantu karena mereka bisa langsung pergi ke sumbernya. Jawaban ini tampaknya mengasumsikan bahwa solusi akan mahal dan menambah kompleksitas. Bagaimana dengan solusi yang murni dan sederhana?
Alex - Hentikan SE
1
@Alex solusi paling sederhana ada di sana: "tidak ada yang mengalahkan pelatihan dan ulasan kode".
Mr.Mindor
2
"tidak ada yang bisa mengalahkannya secara manual" benar sampai seseorang mengotomatiskannya.
Ewan
0

Jawaban Karl adalah 100% benar. Tidak ada cara untuk menjamin kesesuaian. Namun, selain pelatihan dan ulasan kode, pertimbangkan penggunaan alat analisis statis untuk memastikan kepatuhan. (Catatan: Saya mengatakan "selain", karena orang dapat mem-bypass mereka juga dengan cara yang persis sama seperti yang dinyatakan Karl).

Keuntungan menggunakan alat analisis statis adalah menghilangkan analisis kode manusia yang membosankan, mencari contoh "beberapa penggunaan IEnumerable" atau masalah kinerja apa pun dalam minggu yang Anda lihat (atau, setidaknya, yang selalu saya rasakan. melihat ke). Ini akan memungkinkan ulasan kode dan pelatihan untuk fokus pada masalah yang lebih "menarik".

Untuk C #, khususnya, saya telah memasukkan beberapa saran di bawah ini. Tancapkan ini ke lingkungan build Anda dan Anda siap melakukannya. Tetapi, secara umum, tidak peduli bahasa apa yang Anda gunakan, ada alat analisis statis di luar sana.

Salin / tempel langsung dari halaman Wikipedia, gunakan halaman wiki untuk informasi dan tautan terbaru: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET

  • .NET Compiler Platform (Codename Roslyn) - Kerangka kerja sumber terbuka untuk C # dan Visual Basic .NET yang dikembangkan oleh Microsoft .NET. Menyediakan API untuk menganalisis dan memanipulasi sintaks.
  • CodeIt.Right - Menggabungkan analisis kode statis dan refactoring otomatis ke praktik terbaik yang memungkinkan koreksi otomatis kesalahan dan pelanggaran kode; mendukung C # dan VB.NET.
  • CodeRush - Plugin untuk Visual Studio yang memperingatkan pengguna untuk pelanggaran praktik terbaik.
  • FxCop - Analisis statis gratis untuk program Microsoft .NET yang mengkompilasi ke CIL. Standalone dan terintegrasi dalam beberapa edisi Microsoft Visual Studio; oleh Microsoft.
  • NDepend - Menyederhanakan pengelolaan basis kode .NET yang kompleks dengan menganalisis dan memvisualisasikan dependensi kode, dengan menetapkan aturan desain, dengan melakukan analisis dampak, dan dengan membandingkan berbagai versi kode. Terintegrasi ke dalam Visual Studio.
  • Parasoft dotTEST - Analisis statis, pengujian unit, dan plugin peninjauan kode untuk Visual Studio; bekerja dengan bahasa untuk Microsoft .NET Framework dan .NET Compact Framework, termasuk C #, VB.NET, ASP.NET dan Managed C ++.
  • Sonargraph - Mendukung C #, Java dan C / C ++ dengan fokus pada analisis ketergantungan, pemeriksaan arsitektur otomatis, metrik dan kemampuan untuk menambahkan metrik khusus dan pemeriksa kode.
  • StyleCop - Menganalisa kode sumber C # untuk menegakkan serangkaian aturan gaya dan konsistensi. Itu dapat dijalankan dari dalam Microsoft Visual Studio atau diintegrasikan ke dalam proyek MSBuild.
Reginald Blue
sumber
-1

Untuk menguraikan saran "pelatihan dan tinjauan kode" yang diajukan dalam jawaban lain: karena kode yang ingin Anda larang adalah kode hukum, Anda tidak dapat mengandalkan kompilator yang mencegahnya, dan Anda harus mengandalkan proses selanjutnya, ulasan.

Ini dapat (dan harus) mencakup langkah-langkah tinjauan manual dan otomatis:

  • Persiapkan daftar periksa masalah yang diketahui dan ulas ulasan kode manual Anda, satu per satu. Adakan pertemuan berulang untuk meninjau dan memperbarui daftar periksa. Setiap kali bug jahat ditangkap dan dianalisis, tambahkan ke daftar periksa.

  • Tambahkan aturan check-in untuk mencari pola yang diketahui. Ini bisa rumit untuk ditulis, tetapi untuk proyek besar, dari waktu ke waktu, mungkin bermanfaat. TFS memungkinkan Anda untuk menulis aturan dalam C #, dan sistem build lain memiliki kaitannya sendiri. Pertimbangkan untuk menggunakan bangunan berpagar untuk menolak check-in yang sesuai dengan pola. Ya, ini memperlambat pengembangan, tetapi setelah ukuran dan kompleksitas proyek tertentu, memperlambat dev dapat menjadi hal yang baik.

Avner Shahar-Kashtan
sumber
-1

Mungkin kompiler dapat membantu Anda menangkap panggilan yang tidak diinginkan.

Ganti nama kelas / metode kode di lib Anda sendiri yang tidak boleh digunakan oleh klien lib eksternal. Secara alternatif, buatlah kelas / metode internal dan tambahkan internal yang terlihat oleh kelas-kelas yang diizinkan menggunakannya.

Pengguna Lib eksternal akan mendapatkan metode / kelas kesalahan kompilasi tidak ditemukan.

Kelas / metode terlarang dari perpustakaan umum: buat namespace / kelas / metode yang sama di lib Anda

Pengguna lib eksternal akan mendapatkan kesalahan kompilasi karena ditemukan kelas duplikat

[memperbarui]

Tidak perlu benar-benar dalam setiap keadaan mencegah akses ke metode / kelas ini, misalnya dengan refleksi atau hanya semacam penonaktifan, ....

memaksa pemrogram (... klien lib ...) untuk secara aktif mengambil tindakan untuk mengatasi kendala ini jika memungkinkan / diperlukan.

k3b
sumber
Mengundurkan diri ini, bukan hanya karena peretasan yang tidak menyenangkan, tetapi juga mudah diatasi dengan C # (yang mana OP telah menandai pertanyaannya) menggunakan alias eksternal .
David Arno