Yinelemeli yöntemler siklomatik karmaşıklığı azaltır ve desteklenebilirliği artırır mı?


11

Java 8'de C #, JavaScript ve (umarım) gibi modern dillerde yaygın olarak bulunan yinelemeli yöntemler, siklomatik karmaşıklığın kodun anlaşılabilirliği ve desteklenebilirliği üzerindeki etkisini azaltır mı?

Örneğin C # 'da şu kod bulunabilir:

List<String> filteredList = new List<String>();

foreach (String s in originalList){
   if (matches(s)){
      filteredList.add(s);
   }
}

Bu 2'nin basit bir siklomatik karmaşıklığına sahiptir.

Bunu kolayca şöyle yeniden yazabiliriz:

List<String> filteredList = originalList.where(s => matches(s));

Hangi 0 basit bir siklomatik karmaşıklığı vardır.

Bu aslında daha fazla desteklenebilir kodla sonuçlanıyor mu? Bu konuda gerçek bir araştırma var mı?


2
Başlığınız siklomatik karmaşıklığın azaltılmasını soruyor, ancak metniniz CC'de azalma olduğunu varsayar ve sürdürülebilirlik hakkında sorular sorar. Bunun değerli bir soru olma potansiyeli var, başlığı daha doğru olacak şekilde düzenleyebilir misiniz?
Kilian Foth

@KilianFoth Daha iyi mi?
C. Ross

Yinelemeli yöntemleri yinelemeli bir geliştirme yöntemiyle ilişkilendiririm. Bence daha iyi bir terim üst düzey işlevler olacaktır. (Ve bir yana, yöntemlerin bir dönüş türü / geçersizliği vardır, işlevler bir şey döndürür).
Johannes Rudolph

@JohannesRudolph "yöntemlerin dönüş türü / geçersizliği varken işlevler bir şey döndürür" - bu hangi dilde doğrudur? Bunu hiç duymadım; Aslında, şimdiye kadar duyduğum tek gerçek ayrım, yöntemlerin bir sınıfla ilişkilendirilmiş olmasıydı, fonksiyonlar değil.
threed

Yanıtlar:


14

Tahminimce karmaşıklığı daha önce böldünüz / taşıdınız. CC'nizdeki uygulamasını saymadığınız için azaldı .where().

Genel CC gerçekten hareket etmedi, kendi kodunuzun CC'si sadece şimdi çerçevenin koduna taşındığı için azaldı.

Daha sürdürülebilir olduğunu söyleyebilirim. Dilin bir özelliği olduğunda kullanın. Kullandığınız bir "ohh, anlıyorum, akıllıca bir numara" değil, sadece basit bir satır içi azaltma benzeri işlev.


11

Tek yaptığınız, bir metrik olarak siklomatik karmaşıklıktaki bir kusuru vurgulamaktır, kodun karmaşıklığı gerçekten değişmemiştir. İlk örnekte açık bir dalınız var ve ikincisinde zımni bir dal olduğunu anlamalısınız. İkincisi, sözdizimini anlamanız şartıyla ve daha az temel sözdizimi kullandığı için sorun olabilecek daha net ve anlaşılması daha kolaydır.


1
Kendi kodunun siklomatik karmaşıklığının burada azaltıldığı iddia edilebilir, çünkü whereburada muhtemelen bir çerçeve vardır. Bir metrik olarak siklomatik karmaşıklığın burada bile yararlı olduğunu düşünüyorum, çünkü bir işlevi birkaç parçaya bölmek sistemin genel karmaşıklığını azaltmaz (aslında, genellikle biraz artarsa, genellikle bir miktar artar), sistemin bir parçası aşırı derecede karmaşık hale gelir ve parçalanması gerekir.
threed

6

Soruyu objektif olarak cevaplamak için, sürdürülebilirlik için bir çeşit metriğe ihtiyacımız var. Cyclomatic karmaşıklık kendisi maintainability bir ölçüsü değildir, ama bir meali idame ölçmek için bazı metriklerin bir bileşenidir. Örneğin, Sürdürülebilirlik Endeksi için formül şöyledir:

MI = 171 - 5.2 * ln(V) - 0.23 * (G) - 16.2 * ln(LOC)

Gsöz konusu kodun siklomatik karmaşıklığı nerede . Bu nedenle, bir kod parçasının siklomatik karmaşıklığını azaltmak, tanım gereği kodun Sürdürülebilirlik Endeksi'ni ve benzer şekilde siklomatik karmaşıklığı kullanan diğer metrikleri geliştirir .

Bu teklif değişim tür programı yapar olmadığını söylemek zor görünmektedir programcılar için daha rahat; bu muhtemelen (sizin durumunuzda) whereyönteme ne kadar aşina olduklarına bağlıdır .


Uyarı: Sihirli Sayılar! (>_<)
Izkata

Sürdürülebilirlik Endeksi ile ilgili küçük bir sorun var. Üç bileşeni Halstead Hacmi, Siklomatik Karmaşıklık ve Kod Satırlarıdır. Hem Halstead Hacmi hem de Siklomatik Karmaşıklığın Kod Satırlarıyla çok güçlü bir şekilde ilişkili olduğu gösterilmiştir. Bu, SADECE Kod Satırlarına dayanan Sürdürülebilirlik Endeksi için alternatif bir yaklaşık denklemin, neredeyse daha az hesaplama zorluğu ile orijinal kadar neredeyse doğru olacak şekilde türetilebileceği anlamına gelir.
John R. Strohm

@ JohnR.Strohm Sürdürülebilirlik ölçütü olarak yalnızca LOC kullansanız bile benzer bir sonuç elde edeceğinizi düşünüyorum. OP'nin değişimi LOC'u 4'ten 1'e düşürür ve siklomatik karmaşıklığı azaltan diğer değişikliklerin de benzer şekilde LOC'u azaltması muhtemeldir. Her iki durumda da, gerçekten sürdürülebilirliği nasıl tanımladığınız ve ölçtüğünüzle ilgilidir.
Caleb

1
@Caleb: Kabul etti. Yapmaya çalıştığım nokta, insanların çok karmaşık olan bu metrikler ve metrik kombinasyonları için çok sık gittikleri, hemen hemen hepsinin gerçek kod satırları ile düz eski Kod Satırları (LOC) arasında güçlü bir şekilde korele olduklarını fark etmedikleri. ve dolayısıyla LOC'den daha öngörülü veya açıklayıcı bir değeri yoktur.
John R. Strohm

3

Çünkü o gösterilmiştir cyclomatic karmaşıklık (CC) çok güçlü, kod boyutu ile ilişkili olduğunu "o kadar ki CC söylenebilir ki kendi kesinlikle hiçbir açıklama gücüne sahip olmak." gerçekten sorduğunuz şey, "Java 8'de C #, JavaScript ve (umarım) gibi modern dillerde yaygın olarak bulunan yinelemeli yöntemlerin kod boyutunun anlaşılabilirlik ve kodun desteklenebilirliği üzerindeki etkisini azaltıp azaltmadığıdır.

Bu noktada, yanıtın açık olacağı umulur. On yıllardır daha kısa kodların anlaşılması, sürdürülmesi ve desteklenmesinin genellikle daha kolay olduğu bilinmektedir.


2

Eğer Cyclomatic Complexity'nin ham statüsünden bahsediyorsanız, kesinlikle. Sadece 2'den 0'a kadar çenesini çektin.

Pratik (okuma: insan) bakış açısından , karmaşıklığı aslında 2 oranında artırdığınızı iddia ediyorum . Bunun bir noktası, şimdi başka bir programcının bunu anlamak için akıcı sözdizimi LINQ'unu getirmesi veya alması gerektiğinden geliyor. kodu.

Artan zorluğun bir başka noktası Lambda İfadelerini anlamaktan gelir; Bu durumda bir Lambda oldukça basit olsa da , onları tam olarak takdir etmek için yapılması gereken bazı paradigma değişimleri vardır.

Bu durum, kullanmak a.where(x => matches(x, arg))korkunç değildir ve dürüst olmak gerekirse, bazı iş arkadaşlarının ilk kez LINQ ve Lambda ifadelerini görüp çalışmasını sağlamak için harika bir yoldur (Aslında bunu kullanarak bazı eski iş arkadaşlarına LINQ / Lambdas hakkında bir eğitim sundum ve diğer kod kümeleri, büyük bir etki yaratacaktır.) Ancak, bunların kullanımı biraz bilgi gerektirir.

Dikkatli olmanızı öneririm, çünkü LINQ refactor'unun okunması gerçekten bu foreachdöngüden çok daha kötü durumları gördüm .


1

Sübjektif olarak, lambda ifadelerini anlarlarsa geliştirici kitlesine bağlıdır;

List<String> filteredList = originalList.where(s => matches(s));

anlaması daha hızlıdır ve belki biraz daha kolaydır. S ve match () kullanmakla daha fazla ilgilenirim. İkisi de kendini tanımlayıcı değildir;

List<String> filteredList = 
    originalList.where(stringToBeTested => matchesNameTest(stringToBeTested));

Veya

List<String> filteredList = 
        originalList.where(originalListString => matchesNameTest(originalListString));

geliştiriciye daha anlamlı bilgiler verir ve hangi eşleşmenin yapıldığını belirlemek için match () işlevine dalmak zorunda kalmadan analiz etmesi daha kolaydır.

Sürdürülebilirlik sadece kodu anlama yeteneği ile değil, aynı zamanda kodun kavrayabildiği hız ve doğrulukla ilgilidir.


2
Merhaba Ace. Yapıyı vurgulamak için kasıtlı olarak anlamsal içerikten yoksun bir örnek.
C. Ross
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.