Mengapa kompleksitas siklomatik itu penting untuk satu metode?

10

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 ifuntuk 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.

Yassine Badache
sumber
^^^ pertanyaan "kepala panah" mungkin merupakan duplikat yang lebih baik dalam arti menjelaskan cara meningkatkan kode Anda, tetapi saya memilih yang pertama karena penjelasan terperinci menjawab bagian dari pertanyaan Anda tentang kompleksitas siklomatik
nyamuk
Memisahkan suatu metode menjadi bagian-bagian yang lebih kecil tidak mengurangi jumlah total kode yang dieksekusi tetapi membuat jelas tugas-tugas individu yang terjadi; mereka masing-masing dapat dipahami lebih mudah secara individual daripada ketika mereka semua tersangkut dalam keseluruhan yang lebih besar. Paling tidak itu menghilangkan banyak sekali pakai, variabel menengah dari ruang lingkup yang lebih besar.
Doval
1
Untuk kasus yang dijelaskan khusus Anda, saya akan melakukan sesuatu dalam metode utama Anda seperti "A = extractAFrom (sA);" untuk setiap bidang. Anda mungkin dapat membuat nama yang lebih baik karena Anda tahu bidang yang sebenarnya dan kegunaannya.
Tin Man

Jawaban:

32

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.

GhostCat memberi hormat Monica C.
sumber
9
Jadi pada dasarnya ini bukan tentang masalah teknis , tetapi tentang manusia ? Ini terdengar, memang, agak pintar, saya tidak tahu bagaimana saya tidak memikirkannya sebelumnya. Terima kasih!
Yassine Badache
4
Jika demikian, saya dengan sepenuh hati merekomendasikan Anda untuk mendapatkan "Kode Bersih" oleh Robert Martin (Anda mungkin menemukan pdf gratis di jaring). Anda lihat, membuat kode yang dapat dibaca adalah salah satu kebajikan yang paling penting tetapi sangat sering diabaikan oleh seorang programmer yang baik.
GhostCat memberi hormat Monica C.
@YassineBadache CC juga membuat sulit untuk menguji setiap sudut dan celah (cakupan penuh).
Tulains Córdova
Ini adalah inti dari kertas goto Dijkstra juga.
Seth Battin
Dalam pengalaman saya bug hampir selalu dalam metode dengan CC tinggi dan ketika bug dalam metode CC rendah mereka biasanya benar-benar jelas, tidak ada cara bagi mereka untuk bersembunyi melewati jalankan pertama kode. Saya juga hampir tidak pernah harus memodifikasi metode CC rendah - lebih banyak beban yang diambil dari otak.
Loren Pechtel
6

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.

Kilian Foth
sumber
2
Jika "FieldA bergantung pada String sA" sebagai status OP, saya tidak yakin bahwa memindahkan ini ke CalculateFieldA (String sA) membuat kode lebih berbelit-belit.
Taemyr
2

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.

André Stannek
sumber
Meskipun ini adalah jawaban yang bagus, ini sedikit pendek. Akan lebih baik jika Anda bisa memberikan contoh dari apa yang Anda katakan, dan lebih spesifik mengenai pertanyaan yang diajukan oleh OP: "mengapa begitu penting untuk tidak memiliki CC yang terlalu tinggi dalam satu metode?".
Machado
2

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 .

Thomas Owens
sumber
0

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 ifpernyataan ke metode lain menyembunyikan masalah - tetapi apakah ada pola di sana yang dapat Anda abstraksi alih-alih menempelkan n kali? Jika ini merupakan if-elserantai 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?

GoatInTheMachine
sumber
0

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.

Encaitar
sumber
0

Itu tergantung pada berapa banyak waktu yang dihabiskan untuk melihat (siklus otak) pada kode dan memahami apa yang dilakukan kode.

  • Pertimbangkan metode 10 garis - Mungkin perlu beberapa menit untuk memahami apa yang dilakukannya.
  • Pertimbangkan metode 100 garis - Mungkin perlu satu jam atau lebih untuk memahami apa yang sedang dilakukan.
  • Pertimbangkan metode 1000 baris - Mungkin perlu waktu sehari atau lebih untuk memahami apa yang sedang dilakukan.

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.

Jon Raynor
sumber
1
Maaf Ghost Cat menjawab sangat mirip, seharusnya halaman di-refresh.
Jon Raynor