Tek bir yöntem için siklomatik karmaşıklık neden önemlidir?


10

Son zamanlardan beri Eclipse için SonarLint kullanıyorum ve bana çok yardımcı oldu. Ancak, bana siklomatik karmaşıklık hakkında bir soru yöneltti.

SonarLint kabul edilebilir bir CC 10 olarak kabul eder ve bunun ötesinde olduğum bazı durumlar vardır, yaklaşık 5 veya 6 birim. Bu parçalar, değerlerin farklı değişkenlere dayandığı haritacılarla ilişkilidir, örneğin:

  • A Alanı sA dizesine dayanır;
  • B alanı String sB'ye dayanır;
  • C alanı String sC'ye dayanır;
  • vb ...

ifHer alan için bir koyarak başka seçeneğim yok . Bu (neyse ki) seçimim değil, kendi başıma değiştiremediğim zaten var olan ve karmaşık bir sistem.


Sorumun özü şudur: Tek bir yöntemde çok yüksek bir CC'ye sahip olmamak neden bu kadar önemlidir ? Bazı koşullarınızı karmaşıklığı azaltmak için bir veya daha fazla alt yöntemde taşırsanız, genel işlevinizin maliyetini azaltmaz, sadece sorunu başka bir yere taşıyor, sanırım?

(Varsa küçük hatalar için özür dileriz).


DÜZENLE

Sorum, küresel siklomatik karmaşıklığa değil, sadece tek yöntem karmaşıklığına ve yöntem bölünmesine atıfta bulunuyor (Tam olarak ne demek istediğimi açıklamakta zorlanıyorum, üzgünüm). Neden hala her alt yöntemi yürütecek, böylece algoritmaya karmaşıklık ekleyen bir 'süper yönteme' aitse, koşullarınızı daha küçük yöntemlere bölmeye izin veriliyor mu soruyorum.

Bununla birlikte, ikinci bağlantı ( anti-desen hakkında ) çok yardımcıdır.




^^^ "ok başı" sorusu muhtemelen kodunuzu nasıl geliştireceğinizi açıklayan anlamda daha iyi bir kopyadır, ancak siklomatik karmaşıklık hakkındaki sorunuzun bir kısmını yanıtlayan ayrıntılı bir açıklama nedeniyle ilkini seçtim
gnat

Bir yöntemi daha küçük parçalara bölmek, yürütülen kodun toplam miktarını azaltmaz, ancak gerçekleşen bireysel görevleri basitleştirir; her biri, daha büyük bir bütün halinde dolaştıklarından çok daha kolay ayrı ayrı anlaşılabilir. En azından bir kerelik birçok ara ara değişkeni daha geniş kapsamdan kaldırır.
Doval

1
Açıkladığınız özel durum için, birincil yönteminizde "A = extractAFrom (sA);" her alan için. Gerçek alanları ve bunların kullanımlarını bildiğinizden, muhtemelen daha iyi isimler bulabilirsiniz.
Kalay Sihirbazı

Yanıtlar:


32

Buradaki temel şey: "beyin kapasitesi".

Gördüğünüz gibi, kodun ana işlevlerinden biri ... okunacak . Ve kodun okunması ve anlaşılması kolay olabilir; veya zor.

Ve yüksek bir CC'ye sahip olmak, tek bir yöntemde çok sayıda "seviye" anlamına gelir. Ve bu şu anlama gelir: Siz, bir insan okuyucu olarak bu yöntemi anlamakta zorlanacaksınız .

Kaynak kodu okuduğunuzda, beyniniz şeyleri otomatik olarak perspektife sokmaya çalışır: başka bir deyişle - bir çeşit "bağlam" yaratmaya çalışır.

Ve sadece birkaç satır ve çok düşük CC'den oluşan küçük bir yönteme (iyi bir adla) sahip olduğunuzda; o zaman beyniniz bu "bloğu" kolayca kabul edebilir. Siz okudunuz, anlıyorsunuz; YAPILAN.

Diğer yandan, kodunuz yüksek CC'ye sahipse, beyniniz neler olup bittiğini azaltmak için çok sayıda "döngü" harcayacaktır.

Bunu söylemenin başka bir yolu: Basit bir karmaşık şey ağı üzerinden her zaman basit bir karmaşık şey ağını tercih etmeye eğilmelisiniz . Çünkü beyniniz küçük şeyleri anlamada daha iyidir.


9
Yani temelde bu teknik meselelerle değil insanla mı ilgili ? Kulağa gerçekten zekice geliyor, daha önce nasıl düşünmediğimi bilmiyorum. Teşekkürler !
Yassine Badache

4
Eğer öyleyse, gönülden Robert Martin tarafından "Temiz Kod" almanızı öneririm (ağlarda ücretsiz olarak pdf bulabilirsiniz). Görülebilir bir kod oluşturmak , iyi bir programcının en önemli ama çoğu zaman göz ardı edilen erdemlerinden biridir.
GhostCat, Monica C.'yi selamlıyor.

@YassineBadache CC ayrıca her kuytu ve çatıyı test etmeyi zorlaştırır (tam kapsama alanı).
Tulains Córdova


Deneyimlerime göre, hatalar neredeyse her zaman yüksek CC'li yöntemlerde bulunur ve hatalar düşük CC yönteminde olduğunda genellikle tamamen açıktır, kodun ilk çalıştırılmasından sonra saklanmaları mümkün değildir. Ayrıca, neredeyse hiç düşük CC yöntemini değiştirmek zorunda olmadığımı fark ettim - beyinden daha fazla yük alınır.
Loren Pechtel

6

CC, kod kokuları için diğer tüm başparmak kuralları gibi sezgiseldir . Size mutlak bir gerçeği söyleyen başarısız-güvenli bir kriter değildir. Öyle olsaydı, yapılacak makul şey, bu tür yöntemleri dilde yasadışı yapmak ve insanları başka bir şekilde amaçlarına ulaşmaya zorlamak olurdu.

Ancak göstergelerin çalışma şekli bu değildir. Onların işlevi o şeylerin uyarı kullanıcılar için ne Çoğu zaman değildi farkında. Sizin durumunuzda, mantığın kıvrımlı olduğunu ve alternatif çözümlerin onu daha kıvrımlı hale getireceğini biliyorsunuz. Bu nedenle, asıl amacı bir sorun olduğunun farkında olmayan kişilere uyarı vermek olduğunda, ilkel başparmak kuralını yerine getirmeye çalışmanın bir anlamı yoktur .


2
OP alanları olarak "FieldA String sA'ya dayanıyorsa" bunu bir CalculateFieldA (String sA) içine taşımanın daha kıvrımlı kod oluşturduğuna ikna olmadım.
Taemyr

2

Kısacası: Her şey kodunuzun okunabilirliği ve dolayısıyla sürdürülebilirliği ile ilgilidir.

Çok sayıda (iç içe) uzun ve karmaşık bir yönteminiz ifvarsa, aslında ne yaptığını söylemek zorlaşır. Bazı özel yöntemleri çıkarır ve anlamlı bir şekilde adlandırırsanız, çok daha kolaydır.


Bu iyi bir cevap olsa da, biraz kısa. Söylediklerinize bir örnek verebilmeniz ve OP tarafından sorulan soru hakkında daha spesifik olmanız iyi olurdu: "tek bir yöntemde çok yüksek bir CC'ye sahip olmamak neden bu kadar önemlidir?".
Machado

2

Bir yöntemin siklomatik karmaşıklığı, bir yönteme yönelik gerekli olan test durumu sayısıyla ilişkilidir. Spesifik olarak, 10'luk bir siklomatik karmaşıklık, test durumları için metodunuz için toplam dal kapsamına sahip olmak üzere 10'un üst sınır olduğu anlamına gelir. Ayrıca, imkansız yollar eksi olarak test edilmesi gereken yol sayısıyla da ilgilidir.

Bunun ötesinde, diğer hususlar için diğer cevaplara katılıyorum - bir geliştiricinin zihinsel kapasitesi ya da potansiyel sorunların ya da yeniden düzenleme ya da kodun okunabilirliği ve sürdürülebilirliğinin bir göstergesi .


0

CC sadece sezgiseldir ve belirli bir puanın ne kadar 'kötü' olduğu birçok şeye bağlıdır.

Bununla birlikte, her zaman yüksek bir CC'yi yeniden düzenlenebilir / yeniden düzenlenmesi gereken kodu vurgulayan bir şey olarak görmelisiniz. ifİfadeyi başka bir yönteme taşımanın sorunu gizlediğini söylüyorsunuz - ancak n kez kopya yapıştırmak yerine soyutlayabileceğiniz bir model var mı? Uzun bir if-elsezincirse, bunu bir anahtar ifadesine dönüştürebilir veya belki de polimorfizm veya başka bir şey kullanabilir misiniz? Derin yuvalama varsa, koşullu cümlelerinizden bazıları birleştirilebilir mi veya farklı sınıflara bölünmesi gereken ayrı sorumlulukları gösteriyor mu?


0

Siklomatik karmaşıklığı bir uyarı olarak görüyorum. Eğer kodu okuyabilir ve anlamak için çok karmaşık değilse o zaman bu konuda çok endişe olmaz, muhtemelen endişelenmek yanlış daha önemli şeyler vardır, her zaman vardır.

Bahsettiğiniz CC türünü azaltmanın bir yolu, sorunuzu Java etiketi ile etiketlediğiniz için polimorfizm kullanmaktır. Dolayısıyla, kod yolları dize olarak yazmak yerine, iyi adlandırılmış sınıfları kullanabilirsiniz. Bu yardımcı olabilir, ancak bazen aşırıya kaçar ve kodunuzun anlaşılmasını daha da zorlaştırabilir.

Ancak, bakımı zor olacak bir kod işareti olabilir. Yöntemi okurken, her durum için hangi kod yolunu izleyeceğinizi görmek kolay mı? Kod tabanını iyi bilmiyorsanız ve kodda ilgili ancak daha fazla bir şey arıyorsanız, bu yöntemi atlayabilir misiniz? Bazı insanlar açıklayıcı isimleri ile 1/2 çizgi yöntemleri bir sürü kadar bölme yöntemleri savunmak biliyorum ama bazen ben bile değiştirilmesi amaçlanan kod daha okumak zor olduğunu düşünüyorum.

Sonuçta sürdürülebilirlik zor bir sorundur ve hangisinin daha kolay okunacağını düşündüğünüze karar vermek size bağlıdır. Bunu hiç düşünüyor olmanız, doğru yolda olduğunuz anlamına gelir. Unutmayın, bu kodu yıllar içinde deşifre etmeye çalışmak zorunda olan bakıcı siz olabilirsiniz. Bu yüzden onlar için mümkün olduğunca kolaylaştırın.


0

Kodlara bakmak ve kodun ne yaptığını anlamak için ne kadar zaman harcandığına (beyin döngüleri) gelir.

  • 10 satırlık bir yöntem düşünün - Ne yaptığını anlamak için birkaç dakikanızı ayırın.
  • 100 satırlık bir yöntem düşünün - Ne yaptığını anlamak için muhtemelen bir saat veya daha fazla zaman ayırın.
  • 1000 satır yöntemini düşünün - Ne yaptığını anlamak için bir gün veya daha fazla zaman ayırın.

Ayrıca, daha büyük yöntemlerin test edilmesi ve ne tür bir davranışın meydana gelebileceğini tahmin etmesi daha zordur.

Siklomatik karmaşıklık bir ölçüttür. Bu durumda, daha yüksek değerler potansiyel sorunların göstergeleridir. Karmaşık kodun anlaşılması daha uzun sürer ve muhtemelen daha az karmaşık yöntemler kadar kapsamlı bir şekilde test edilmez. Bu nedenle, yeniden düzenleme ve bakım amacıyla bu önlemle kodun hangi alanlarının karmaşık olduğuna dikkat etmek önemlidir.

Dikkate alınması gereken başka bir şey, karmaşık kodu güncellemektir. Analiz yaparken, bir geliştirici kod değiştirmenin karmaşıklığına bakarak az ya da çok riskli olduğunu bildirebilir.

Dolayısıyla, karar verme amaçları için kullanılabilen ve kullanılabilen karmaşıklığı ölçmek için çok değer vardır.


1
Üzgünüm Ghost Cat cevap çok benzer, yenilenmiş sayfa olması gerekir.
Jon Raynor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.