Sedikit latar belakang: Sebagai pemimpin tim saya menggunakan NDepend seminggu sekali untuk memeriksa kualitas kode kami. Khususnya cakupan uji, baris kode dan metrik kompleksitas siklomatik sangat berharga bagi saya. Tetapi ketika sampai pada levelisasi dan siklus ketergantungan saya sedikit ... prihatin. Patrick Smacchia memiliki posting blog yang bagus yang menggambarkan tujuan levelisasi.
Agar lebih jelas: Di bawah "siklus ketergantungan" saya memahami referensi melingkar antara dua ruang nama.
Saat ini saya sedang mengerjakan kerangka GUI berbasis Windows CE untuk instrumen yang tertanam - pikirkan saja platform grafis Android tetapi untuk instrumen yang sangat rendah. Kerangka kerja ini adalah perakitan tunggal dengan sekitar 50.000 baris kode (tidak termasuk tes). Kerangka kerja dibagi menjadi ruang nama berikut:
- Navigasi Inti & Subsistem Menu
- Subsistem Layar (Penyaji / Tampilan / ...)
- Lapisan Kontrol / Widget
Hari ini saya menghabiskan setengah hari untuk mencoba membawa kode ke tingkat yang tepat [terima kasih kepada Resharper tidak ada masalah secara umum] tetapi dalam semua kasus beberapa siklus ketergantungan ada.
Jadi pertanyaan saya: Seberapa ketat Anda mengikuti aturan "Tidak Ada Siklus Ketergantungan"? Apakah levelisasi benar-benar penting?
sumber
Jawaban:
Baru-baru ini saya menulis 2 buku putih, yang diterbitkan di Simple-Talk tentang topik arsitektur kode .NET (buku pertama adalah tentang .NET assemblies, buku kedua tentang ruang nama dan levelisasi):
Mempartisi Basis Kode Anda Melalui. NET Assemblies dan Proyek Visual Studio
Mendefinisikan Komponen .NET dengan Namespaces
Ya itu!
Kutipan dari buku putih ke-2:
(...)
sumber
Saya tidak pernah mengizinkan dependensi melingkar antara kelas atau ruang nama. Di C #, Java, dan C ++ Anda selalu dapat memutus ketergantungan kelas melingkar dengan memperkenalkan antarmuka.
Pengodean terlebih dahulu menyulitkan untuk memperkenalkan dependensi melingkar.
sumber
Itu selalu merupakan pertukaran: Anda harus memahami biaya dependensi untuk memahami mengapa dependensi harus dihindari. Dengan cara yang sama, jika Anda memahami biaya ketergantungan, Anda dapat lebih baik memutuskan apakah itu layak dalam kasus spesifik Anda.
Misalnya, dalam video game konsol, kita sering mengandalkan dependensi yang memerlukan hubungan informasi yang erat, sebagian besar untuk alasan kinerja. Itu bagus sejauh kita tidak harus sefleksibel alat edisi misalnya.
Jika Anda memahami kendala dalam penyihir yang harus dijalankan oleh perangkat lunak Anda (menjadi perangkat keras, OS, atau hanya mendesain (seperti "UI yang lebih sederhana yang kami bisa")) maka haruslah mudah untuk memilih memahami mana ketergantungan tidak boleh dilakukan dan yang mana baik.
Tetapi jika Anda tidak memiliki alasan yang baik dan jelas, hindari ketergantungan yang Anda bisa. Kode dependen adalah neraka sesi-debug.
sumber
Setiap kali topik ini dibahas, para peserta biasanya kehilangan situs perbedaan antara siklus build-time dan run-time. Yang pertama adalah apa yang disebut John Lakos sebagai "desain fisik," sedangkan yang terakhir pada dasarnya tidak relevan dengan diskusi (jangan terpaku pada siklus run-time, seperti yang dibuat oleh callback).
Ini mengatakan, John Lakos sangat ketat tentang menghilangkan semua siklus (build-time). Bob Martin, bagaimanapun, mengadopsi sikap bahwa hanya siklus antara binari (misalnya DLL, executable) yang signifikan dan harus dihindari; dia percaya siklus antar kelas dalam biner tidak terlalu penting.
Saya pribadi memegang pandangan Bob Martin tentang hal ini. Namun, saya masih memperhatikan siklus antara kelas karena tidak adanya siklus seperti itu membuat kode lebih mudah bagi orang lain untuk membaca dan belajar.
Akan tetapi, harus ditunjukkan bahwa kode apa pun yang Anda buat dengan Visual Studio tidak mampu memiliki dependensi melingkar di antara binari (baik kode asli atau dikelola). Jadi masalah paling buruk dengan siklus telah dipecahkan untuk Anda. :)
sumber
Hampir sepenuhnya, karena siklus dependensi tipe-bangunan tidak nyaman di Haskell, dan tidak mungkin di Agda dan Coq, dan itu adalah bahasa yang biasanya saya gunakan.
sumber