Saya menggunakan SonarLint untuk Eclipse sejak baru-baru ini, dan itu banyak membantu saya. Namun, itu menimbulkan pertanyaan kepada saya tentang kompleksitas siklomatik.
SonarLint dianggap sebagai CC yang dapat diterima dari 10, dan ada beberapa kasus di mana saya berada di luarnya, sekitar 5 atau 6 unit. Bagian-bagian tersebut terkait dengan pemetaan di mana nilainya bergantung pada variabel yang berbeda, misalnya:
- Bidang A bergantung pada String sA;
- Field B bergantung pada String sB;
- Field C bergantung pada String sC;
- dll ...
Saya tidak punya pilihan lain yang menempatkan if
untuk setiap bidang. Ini bukan pilihan saya (untungnya) tetapi sistem yang sudah ada dan kompleks yang tidak dapat saya ubah sendiri.
Inti dari pertanyaan saya adalah: mengapa begitu penting untuk tidak memiliki CC yang terlalu tinggi dalam satu metode ? Jika Anda memindahkan beberapa kondisi Anda dalam satu atau lebih sub-metode untuk mengurangi kerumitan, itu tidak mengurangi biaya fungsi keseluruhan Anda, itu hanya memindahkan masalah ke tempat lain, saya kira?
(Maaf untuk kesalahan kecil, jika ada).
EDIT
Pertanyaan saya tidak merujuk pada kompleksitas siklomatik global, tetapi hanya pada kompleksitas metode tunggal dan pemisahan metode (saya kesulitan menjelaskan apa yang sebenarnya saya maksud, maaf). Saya bertanya mengapa bisa membagi kondisi Anda menjadi metode yang lebih kecil jika masih milik 'metode super', yang hanya akan mengeksekusi setiap sub-metode, sehingga menambah kompleksitas pada algoritme.
Namun, tautan kedua ( tentang pola anti ) sangat membantu.
sumber
Jawaban:
Hal inti di sini: "kapasitas otak".
Anda lihat, salah satu fungsi utama kode adalah ... untuk dibaca . Dan kode bisa mudah dibaca dan dipahami; atau sulit.
Dan memiliki CC tinggi hanya menyiratkan banyak "level" dalam satu metode. Dan itu menyiratkan: Anda, sebagai pembaca manusia akan kesulitan memahami metode itu.
Ketika Anda membaca kode sumber, otak Anda secara otomatis mencoba untuk meletakkan segala sesuatu ke dalam perspektif: dengan kata lain - ia mencoba membuat beberapa bentuk "konteks".
Dan ketika Anda memiliki metode kecil (dengan nama baik) yang hanya terdiri dari beberapa baris, dan CC sangat rendah; maka otak Anda dapat dengan mudah menerima "blok" ini. Anda membacanya, Anda memahaminya; DIBUAT
Di sisi lain, jika kode Anda memiliki CC tinggi, otak Anda akan menghabiskan banyak "siklus" lebih banyak untuk mengurangi apa yang sedang terjadi.
Cara lain untuk mengatakan itu: Anda harus selalu condong ke arah yang lebih suka jaringan yang kompleks dari hal-hal sederhana daripada jaringan yang sederhana dari hal-hal yang kompleks. Karena otak Anda lebih baik dalam memahami hal-hal kecil.
sumber
CC, seperti semua aturan praktis lainnya untuk bau kode, adalah heuristik . Bukan kriteria gagal-aman yang memberi tahu Anda kebenaran absolut. Jika ya, hal yang wajar untuk dilakukan adalah membuat metode seperti itu ilegal dalam bahasa dan memaksa orang untuk mencapai tujuan mereka dengan cara lain.
Tapi itu bukan cara indikator bekerja. Sebagian besar waktu fungsi mereka adalah untuk orang-orang waspada dari hal-hal yang mereka tidak menyadari. Dalam kasus Anda, Anda sadar bahwa logika berbelit-belit dan solusi alternatif akan membuatnya lebih berbelit-belit. Oleh karena itu tidak ada gunanya mencoba memenuhi aturan praktis primitif, ketika tujuan utamanya adalah untuk mengeluarkan peringatan kepada orang-orang yang tidak sadar bahwa ada masalah.
sumber
Singkatnya: ini semua tentang keterbacaan dan karenanya pemeliharaan kode Anda.
Jika Anda memiliki metode yang panjang dan rumit dengan banyak (bersarang)
if
, menjadi sulit untuk mengatakan apa yang sebenarnya dilakukannya. Jika Anda mengekstrak beberapa metode pribadi dan menamainya dengan cara yang bermakna, itu jauh lebih mudah.sumber
Kompleksitas siklus suatu metode terkait dengan jumlah kasus uji yang diperlukan untuk suatu metode. Khususnya, kompleksitas siklomatik 10 berarti bahwa 10 adalah batas atas untuk kasus uji untuk memiliki cakupan cabang total untuk metode Anda. Ini juga terkait dengan jumlah jalur yang harus diuji, minus jalur yang mustahil.
Di luar itu, saya setuju dengan jawaban lain untuk pertimbangan lain - kapasitas mental pengembang atau indikator masalah potensial atau refactoring atau ukuran keterbacaan dan pemeliharaan kode .
sumber
CC hanyalah heuristik, dan seberapa 'buruk' skor tertentu tergantung pada banyak hal.
Yang mengatakan, Anda harus selalu melihat CC tinggi sebagai sesuatu yang menyoroti kode yang bisa / harus dire-refored. Anda mengatakan bahwa memindahkan
if
pernyataan ke metode lain menyembunyikan masalah - tetapi apakah ada pola di sana yang dapat Anda abstraksi alih-alih menempelkan n kali? Jika ini merupakanif-else
rantai panjang , dapatkah Anda mengubahnya menjadi pernyataan peralihan, atau mungkin menggunakan polimorfisme, atau yang lainnya? Jika ada sarang yang dalam, bisakah beberapa klausa kondisional Anda digabungkan, atau apakah ini menunjukkan tanggung jawab terpisah yang harus dibagi ke dalam kelas yang berbeda?sumber
Saya melihat kompleksitas siklomatik sebagai peringatan. Jika Anda dapat membaca kode dan tidak terlalu rumit untuk memahami maka saya tidak akan terlalu khawatir tentang hal itu, mungkin ada hal-hal yang lebih penting salah untuk dikhawatirkan, selalu ada.
Salah satu cara untuk mengurangi jenis CC yang Anda sebutkan adalah dengan menggunakan polimorfisme, karena Anda telah menandai pertanyaan Anda dengan tag Java. Jadi, alih-alih jalur kode yang diketik secara ketat, Anda dapat menggunakan kelas yang diberi nama dengan baik. Ini bisa membantu, tetapi kadang-kadang berlebihan dan dapat membuat kode Anda lebih sulit untuk dipahami.
Namun, itu bisa menjadi tanda kode yang akan sulit dipertahankan. Saat membaca metode ini, apakah mudah untuk melihat jalur kode mana yang akan Anda turun untuk setiap kasus? Apakah Anda dapat melewati metode ini jika Anda tidak tahu basis kode dengan baik dan sedang mencari sesuatu yang terkait tetapi lebih lanjut dalam kode? Saya tahu beberapa orang menganjurkan metode pemisahan ke banyak metode 1/2 baris dengan nama deskriptif, tetapi kadang-kadang saya pikir itu lebih sulit untuk dibaca daripada kode yang dimaksudkan untuk diganti.
Pada akhirnya pemeliharaan adalah masalah yang sulit dan terserah Anda untuk memutuskan mana yang menurut Anda akan lebih mudah dibaca. Fakta bahwa Anda memikirkan hal ini sama sekali berarti Anda berada di jalur yang benar. Ingat saja, pengelola yang harus mencoba menguraikan kode ini dalam waktu bertahun-tahun mungkin Anda. Jadi buatlah semudah mungkin bagi mereka.
sumber
Itu tergantung pada berapa banyak waktu yang dihabiskan untuk melihat (siklus otak) pada kode dan memahami apa yang dilakukan kode.
Metode yang lebih besar juga lebih sulit untuk diuji dan lebih sulit untuk memprediksi perilaku seperti apa yang dapat terjadi.
Kompleksitas siklus adalah ukuran. Dalam hal ini, nilai yang lebih tinggi adalah indikator masalah potensial. Kode kompleks membutuhkan waktu lebih lama untuk memahami pemahaman dan mungkin tidak diuji selengkap metode yang tidak rumit. Jadi, penting untuk dicatat area kode mana yang kompleks dengan ukuran ini untuk tujuan refactoring dan pemeliharaan.
Satu hal yang perlu dipertimbangkan adalah memperbarui kode kompleks. Saat melakukan analisis, pengembang dapat melaporkan bahwa mengubah kode lebih atau kurang berisiko dengan melihat kerumitannya.
Jadi, ada banyak nilai untuk mengukur kompleksitas yang dapat dimanfaatkan dan digunakan untuk tujuan pengambilan keputusan.
sumber