Wie verbessern Sie die Zyklomatische Komplexität?
Zyklomatische Komplexität hoch sein wird, für Methoden mit einer hohen Anzahl von Entscheidungs-Anweisungen, einschließlich if/while/for-Anweisungen. So wie wir das verbessern?
Ich bin Umgang mit einem großen Projekt, wo ich bin soll reduziert, die CC für Methoden, CC > 10. Und es gibt viele Methoden, mit diesem problem. Unten werde ich die Liste unten einige zB von code-Muster (nicht die tatsächlichen code) mit den Problemen, die ich je erlebt habe. Ist es möglich, dass Sie vereinfacht werden?
Beispiel von Fällen, die in vielen Entscheidung Aussagen:
Fall 1)
if(objectA != null) //objectA is a pass in as a parameter
{
objectB = doThisMethod();
if(objectB != null)
{
objectC = doThatMethod();
if(objectC != null)
{
doXXX();
}
else{
doYYY();
}
}
else
{
doZZZ();
}
}
Fall 2)
if(a < min)
min = a;
if(a < max)
max = a;
if(b > 0)
doXXX();
if(c > 0)
{
doYYY();
}
else
{
doZZZ();
if(c > d)
isTrue = false;
for(int i=0; i<d; i++)
s[i] = i*d;
if(isTrue)
{
if(e > 1)
{
doALotOfStuff();
}
}
}
Fall 3)
//note that these String Constants are used elsewhere as diff combination,
//so you can't combine them as one
if(e.PropertyName.Equals(StringConstants.AAA) ||
e.PropertyName.Equals(StringConstants.BBB) ||
e.PropertyName.Equals(StringConstants.CCC) ||
e.PropertyName.Equals(StringConstants.DDD) ||
e.PropertyName.Equals(StringConstants.EEE) ||
e.PropertyName.Equals(StringConstants.FFF) ||
e.PropertyName.Equals(StringConstants.GGG) ||
e.PropertyName.Equals(StringConstants.HHH) ||
e.PropertyName.Equals(StringConstants.III) ||
e.PropertyName.Equals(StringConstants.JJJ) ||
e.PropertyName.Equals(StringConstants.KKK))
{
doStuff();
}
InformationsquelleAutor yeeen | 2010-12-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fall 1 - den Umgang mit diesem einfach durch refactoring in kleinere Funktionen. E. g. der folgende Codeausschnitt könnte eine Funktion:
Fall 2 - genau der gleiche Ansatz. Nehmen Sie den Inhalt des else-Klausel in einer kleineren Hilfsfunktion
Fall 3 - machen Sie eine Liste der Zeichenfolgen, die Sie wollen, zu überprüfen, und machen Sie eine kleine helper-Funktion vergleicht eine Zeichenkette mit vielen Optionen (könnte weiter vereinfacht werden mit linq)
Reduzierung zyklomatische Komplexität führt oft zu mehr code insgesamt. Aber alle neuen code, macht einen ganz bestimmten job und kann sein Gerät getestet leicht. Anstatt das erstellen von Objekten innerhalb Ihrer Methode sehen in dependency injection/constructor injection und sehen, wenn Sie können übergeben Sie in. Schauen Sie in Fabriken oder generator Muster für die Erstellung komplexer Objekte, wenn erforderlich, usw.. Es hängt alles von Ihrer spezifischen Fall, aber wenn Sie finden, dass die Schichten sind fest miteinander verbunden und verknüpft dann Ihre Architektur ist nicht gut, da dass nicht der Fall sein sollte.
InformationsquelleAutor Mark Heath
Sollten Sie die Umgestaltung Replace Conditional with Polymorphism zu verringern CC.
Den Unterschied zwischen bedingtem einen polymorphen code, der in der polymorphe code die Entscheidung getroffen wird, zur Laufzeit. Dies gibt Ihnen mehr Flexibilität zum hinzufügen\ändern\entfernen von Bedingungen, ohne den code ändern. Testen kann man die Verhaltensweisen, die separat mithilfe von unit-tests verbessert die Testbarkeit. Auch da wird es weniger bedingten code bedeutet, dass der code ist einfach zu Lesen und CC ist weniger.
Weitere Blick in behavioral design patterns esp. Strategie.
Ich würde den ersten Fall wie diesem zu entfernen, die Bedingungen und damit den CC. Außerdem der code wird Objekt-Orientiert, lesbar und überprüfbar, wie gut.
Im zweiten Fall tun es die gleiche war wie die erste.
Im Dritten Fall -
Naja .. wir entschuldigen uns für die schlechte Formatierung . Der link ist hier - en.wikipedia.org/wiki/Null_Object_pattern. Die Null-Objekt-pattern zum Kapseln das Verhalten, der Umgang mit der null-Zulässigkeit des Objekts in eine Klasse. So haben Sie gewohnt, Ihren code übersät mit Null Überprüft. So können Sie vermeiden, wenn die Bedingungen für Null-Prüfungen ist ein Fall von Polymorphismus ersetzen bedingten Logik.
Ich habe auch ausgearbeitet die Antwort mit einigen zusätzlichen Beschreibung oben. Überprüfen Sie bitte.
Die Nummer 4 in der "Beziehen sich auf [Null-Objekt-Pattern][4]" bezieht sich auf irgendwo in der wiki? Sorry, habe ich nicht fangen.
Und warum gibt es 2 EmptyObjectA Klassen, sollte es EmptyObjectB und EmptyObjectC statt? Cos, wenn objectA null ist, macht es nichts. Wo ist GetObjectB()? Ich bin immer noch verwirrt.
InformationsquelleAutor Unmesh Kondolikar
Ich bin kein C# Programmierer, aber ich werde einen Stich an Sie.
Im ersten Fall würde ich sagen, dass die Objekte nicht null sein in den ersten Platz. Wenn dies unvermeidbar ist (es ist in der Regel vermeidbar), dann würde ich die frühe Rückkehr Muster:
Zweiten Fall ist natürlich nicht realistisch code, aber ich zumindest würde eher sagen:
eher als zwei getrennte ifs.
Haben und im letzten Fall würde ich speichern Sie die Zeichenfolgen geprüft werden in einem array/vector/anzeigen und verwenden, die Container-Methoden zu tun, die Suche.
Und schließlich, obwohl die zyklomatische Komplexität ist "eine gute Sache" (tm) und ich verwende es selbst, es gibt einige Funktionen, die natürlich ein bisschen kompliziert - validieren von Benutzereingaben ist ein Beispiel. Ich Wünsche mir oft, dass das CC-tool ich benutze (Quelle Monitor zu http://www.campwoodsw.com - kostenlos und sehr gut) unterstützt eine white-Liste der Funktionen, die ich wissen muss und Komplex, die ich nicht wollen, es zu Kennzeichnen.
InformationsquelleAutor unquiet mind
Den letzten, wenn in Fall 2 kann vereinfacht werden:
kann ersetzt werden durch
Fall 3 kann umgeschrieben werden als:
können Sie auch das string-array in eine
HashSet<String>
zu bekommen O(1) Leistung.InformationsquelleAutor CodesInChaos