V für Vendetta? Wenn sprechende Namen helfen

V für Vendetta? Wenn sprechende Namen helfen

Clean Code als Dogma?

Ich bin heute mal wieder über eine Quellcodestelle gestolpert, die mich nicht in Ruhe ließ. Man selbst schreibt ja durchaus auch immer wieder undurchsichtigen Code. Clean Code muss ja kein Dogma sein, aber wenigstens einigermaßen sprechende Namen sollte man doch verwenden können. Zumindest fallen mir immer wieder Stellen auf, die man hätte klarer schreiben sollen. Auch verfalle ich immer noch wieder mal in eine schlechte Angewohnheit. Mal eben. Quick and dirty. Um ein Problem zu fixen, was schnell erledigt werden muss. Es bekommt dann ein „//TODO:“ hinten dran und man hofft, dass man eines Tages die Zeit hat, das schön zu machen. Hat man nicht… Alles was man hat, ist das Problem. Denn wenn man das nächste Mal an der Stelle arbeiten muss, dann macht man es doch erstmal schön.

Dennoch gibt es Code, bei dem man sieht, dass sich jemand Mühe gab. Vielleicht hat derjenige einfach nur falsch eingeschätzt, wie deutlich er sein muss. Oder er hatte Wissen, das seinen Quelltext deutlich macht. Manchmal gibt es dann aber Code, bei dem man eigentlich nur mit dem Kopf schütteln kann.

Aber schaut selbst, was zur Hölle sollte mir das folgende Stück Quelltext sagen? Und wofür steht das „v“ was ja wohl eine tragende Rolle erhält.

decimal v;
decimal e = 0; 
decimal nf = 0; 
foreach(FehlerStatisik fs in ms.Fehlerstatistik) 
{ if(fs.fehlerCode == -1) nf = fs.anzahl; e += fs.anzahl; } 
if((e > 0) && (nf > 0)) { v = (nf / e) * 100; v = Math.Round(v, 2); v = 100 - v; } 
else if((nf == 0) && (e > 0)) v = 100; 
else v = -1;

Sprechende Namen

Das war ein wunderbares Beispiel für eine Variablenbenennung welche auch als abschreckendes Beispiel für Robert Martins „Clean Code“ hätte Verwendung finden können. Um der „Boyscout-Rule“ zu folgen (endlich habe ich einen Namen für das, was man eh immer macht) habe ich die Zeilen in eine Methode gesteckt. Refactoring-Tool sei dank. Denn der Bereich stand natürlich inmitten eines Foreach Blocks. Dann habe ich Schritt für Schritt die Variablen umbenannt, bis sich mir im Zusammenhang mit der späteren Verwendung der Sinn entschloss. Sprechende Namen hätten das von vorneherein erübrigt. Entstanden ist der folgende Quelltext:

private decimal CalculateVerfuegbarkeit(MaschinenStatistik maschinenStatistik)
{
decimal verfuegbarkeit;
decimal summeMesswerte = 0;
decimal nichterreichbarAnzahl = 0;

foreach(FehlerStatisik fs in maschinenStatistik.Fehlerstatistik)
{
if(fs.fehlerCode == -1)
nichterreichbarAnzahl = fs.anzahl;

summeMesswerte += fs.anzahl;
}

//gab es Ausfälle -> Verfügbarkeitsanteil berechnen
if((summeMesswerte > 0) && (nichterreichbarAnzahl > 0))
{
decimal verfuegbarkeitQuotient = (nichterreichbarAnzahl / summeMesswerte) * 100;
verfuegbarkeit = 100 - Math.Round(verfuegbarkeitQuotient, 2);
}
else
//Idealfall: keine Ausfälle, aber Messwerte -> gültig
if((nichterreichbarAnzahl == 0) && (summeMesswerte > 0))
verfuegbarkeit = 100;
else //Spezialfälle: ungültige Werte etc.
verfuegbarkeit = -1;

return verfuegbarkeit;
}

Nach dem Refactoring ist vor dem Refactoring

Demnächst werde ich das Ganze noch ein wenig anpassen. Linq kann hier sicher noch ein wenig was ausmachen. Aber immerhin weiß ich jetzt, wozu der Kram überhaupt gut ist. Und wenn es drauf ankommt, kann ich Unit-Tests nachschieben, um zu schauen, ob das Ding überhaupt richtig funktioniert… Aber das Wichtigste ist, Clean Code ist nicht nur das Ziel, sondern auch ein Weg. Auf gehts!

Michael Grünwaldt

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert