Apakah metode berulang seperti yang biasa ditemukan dalam bahasa modern seperti C #, JavaScript, dan (mudah-mudahan) di Java 8 mengurangi dampak kompleksitas siklomatik pada pemahaman dan dukungan kode?
Misalnya dalam C # kita mungkin memiliki kode berikut:
List<String> filteredList = new List<String>();
foreach (String s in originalList){
if (matches(s)){
filteredList.add(s);
}
}
Ini memiliki kompleksitas siklomatik sederhana 2.
Kita dapat dengan mudah menulis ulang ini sebagai:
List<String> filteredList = originalList.where(s => matches(s));
Yang memiliki kompleksitas siklomatik sederhana 0.
Apakah ini benar-benar menghasilkan kode yang lebih dapat didukung? Apakah ada penelitian aktual tentang topik ini?
cyclomatic-complexity
C. Ross
sumber
sumber
Jawaban:
Dugaan saya adalah bahwa Anda baru saja membagi / memindahkan kompleksitas. Itu menurun karena Anda tidak menghitung implementasi
.where()
di CC Anda.CC keseluruhan belum benar-benar bergerak, CC kode Anda sendiri menurun, hanya karena sekarang dipindahkan ke kode kerangka kerja.
Saya akan mengatakan itu lebih mudah dikelola. Ketika itu fitur bahasa, gunakan itu. Ini bukan "ohh, saya mengerti, ini adalah trik pintar" yang Anda gunakan, hanya fungsi inline-like sederhana.
sumber
Yang Anda lakukan hanyalah menyoroti cacat dalam kompleksitas siklomatik sebagai metrik, kompleksitas kode tidak berubah. Anda memiliki cabang eksplisit dalam contoh pertama dan perlu memahami ada cabang tersirat di yang kedua. Yang kedua lebih jelas dan lebih mudah dipahami asalkan Anda memahami sintaksis, dan karena menggunakan sintaksis yang kurang mendasar yang mungkin menjadi masalah.
sumber
where
sini kemungkinan dari suatu kerangka kerja. Saya pikir kompleksitas siklomatik sebagai metrik berguna bahkan di sini karena, sementara memecah fungsi menjadi beberapa tidak mengurangi keseluruhan kompleksitas sistem (memang, itu sering meningkatkannya, jika hanya sedikit), itu membantu Anda menentukan kapan satu sepotong sistem menjadi terlalu rumit dan perlu dipecah.Untuk menjawab pertanyaan secara obyektif, kita perlu semacam metrik untuk pemeliharaan. Kompleksitas siklus itu sendiri bukan merupakan ukuran kemampuan pemeliharaan, tetapi merupakan komponen dari beberapa metrik yang dimaksudkan untuk mengukur kemampuan pemeliharaan. Misalnya, rumus untuk Indeks Maintainability adalah:
di mana
G
kompleksitas cyclomatic dari kode tersebut. Oleh karena itu, mengurangi kompleksitas cyclomatic dari sepotong kode menurut definisi meningkatkan Maintainability Index dan metrik lainnya yang juga menggunakan kompleksitas cyclomatic .Sulit untuk mengatakan apakah jenis perubahan yang Anda usulkan membuat program tampak lebih dapat dipertahankan oleh programmer; yang mungkin tergantung pada seberapa akrab mereka dengan
where
metode (dalam kasus Anda) .sumber
(>_<)
Karena telah diperlihatkan bahwa kompleksitas siklomatik (CC) berkorelasi sangat kuat dengan ukuran kode, "sedemikian rupa sehingga CC dapat dikatakan sama sekali tidak memiliki kekuatan penjelasnya sendiri." apa yang sebenarnya Anda tanyakan adalah apakah "metode berulang seperti yang biasa ditemukan dalam bahasa modern seperti C #, JavaScript, dan (mudah-mudahan) di Java 8 mengurangi dampak ukuran kode pada pemahaman dan dukungan kode."
Pada titik itu, orang akan berharap bahwa jawabannya akan jelas. Sudah dikenal selama beberapa dekade bahwa kode yang lebih pendek umumnya lebih mudah dipahami, dipelihara, dan didukung.
sumber
Jika Anda berbicara tentang stat baku Kompleksitas Cyclomatik, tentu saja. Anda baru saja memindahkannya dari 2 menjadi 0. Jika Anda menggunakan angka, untung murni, semuanya.
Dari perspektif praktis (baca: manusia), saya berpendapat Anda benar-benar telah meningkatkan kompleksitasnya dengan 2. Satu hal yang berasal dari kenyataan bahwa sekarang beberapa programmer lain harus membawa atau mendapatkan pengetahuan tentang LINQ fasih-sintaks untuk memahami ini kode.
Poin lain dari meningkatnya kesulitan berasal dari memahami Ekspresi Lambda; meskipun Lambda cukup mudah dalam hal ini , ada beberapa perubahan paradigma yang harus dilakukan untuk sepenuhnya menghargai mereka.
Kasus ini, menggunakan
a.where(x => matches(x, arg))
tidak mengerikan, dan dalam semua kejujuran adalah cara yang bagus untuk membuat beberapa rekan kerja melihat dan bekerja dengan ekspresi LINQ dan Lambda untuk pertama kalinya (saya benar-benar mempresentasikan tutorial tentang LINQ / Lambdas kepada beberapa mantan rekan kerja yang menggunakan ini dan set kode lain, untuk efek yang besar.) Namun, penggunaannya memang membutuhkan pengetahuan.Saya sarankan hati-hati, karena saya telah melihat kasus-kasus di mana refactor LINQ sebenarnya jauh lebih buruk untuk dibaca daripada apa
foreach
loop itu menjadi.sumber
Secara subyektif, itu tergantung pada audiens pengembang, jika mereka memahami ekspresi lambda, maka;
lebih cepat dimengerti, dan mungkin sedikit lebih mudah. Saya akan lebih khawatir tentang penggunaan s, dan match (). Baik deskriptif diri, seperti;
Atau
memberikan pengembang informasi yang lebih bermakna dan lebih mudah untuk dianalisis, tanpa harus menyelami fungsi pertandingan () untuk menentukan pertandingan apa yang sedang dilakukan.
Maintainability bukan hanya tentang kemampuan untuk memahami kode, tetapi terutama tentang kecepatan dan ketepatan yang dapat digunakan untuk memahami kode.
sumber