"Entitäten dürfen nicht über die Notwendigkeit hinaus multipliziert werden."
- Ockhams Rasiermesser
Code muss so einfach wie möglich sein. Bugs verstecken sich gerne zwischen Komplexität, weil sie dort schwer zu erkennen sind. Was macht Code einfach?
Kleine Einheiten (Dateien, Funktionen, Klassen) sind eine gute Idee . Kleine Einheiten sind einfach zu verstehen, weil Sie weniger Dinge auf einmal verstehen müssen. Normale Menschen können nur 7 Konzepte gleichzeitig unter einen Hut bringen. Die Größe wird jedoch nicht nur in Codezeilen gemessen . Ich kann so wenig Code wie möglich schreiben, indem ich den Code „spiele“ (indem ich kurze Variablennamen wähle, „clevere“ Abkürzungen nehme und so viel Code wie möglich in eine einzelne Zeile zerschmettere), aber das Endergebnis ist nicht einfach. Der Versuch, solchen Code zu verstehen, ähnelt eher dem Reverse Engineering als dem Lesen.
Eine Möglichkeit, eine Funktion zu verkürzen, besteht darin, verschiedene Hilfsfunktionen zu extrahieren. Das kann eine gute Idee sein, wenn es ein in sich geschlossenes Stück Komplexität extrahiert . Für sich genommen ist diese Komplexität viel einfacher zu verwalten (und zu testen!) Als wenn sie in ein nicht zusammenhängendes Problem eingebettet ist.
Aber jeder Funktionsaufruf hat einen kognitiven Overhead : Ich muss nicht nur den Code in meinem aktuellen Code verstehen, sondern auch verstehen, wie er von außen mit Code interagiert . Ich denke, es ist fair zu sagen, dass die von Ihnen extrahierte Funktion mehr Komplexität in die Funktion einbringt als sie extrahiert . Das ist es, was Ihr Chef unter " kleinen Funktionen" versteht, da Sie gezwungen sind, in jede kleine Funktion zu wechseln, um zu sehen, was der Code tut. "
Manchmal sind langweilige Funktionen unglaublich einfach zu verstehen, selbst wenn sie Hunderte von Zeilen lang sind. Dies tritt in der Regel im Initialisierungs- und Konfigurationscode auf, z. B. beim Erstellen einer grafischen Benutzeroberfläche von Hand ohne Drag-and-Drop-Editor. Es gibt kein eigenständiges Stück Komplexität, das Sie vernünftigerweise extrahieren könnten. Aber wenn die Formatierung lesbar ist und es einige Kommentare gibt, ist es nicht schwierig zu verfolgen, was passiert.
Es gibt viele andere Komplexitätsmetriken: Die Anzahl der Variablen in einem Bereich sollte so gering wie möglich sein. Das heißt nicht, dass wir Variablen vermeiden sollten . Das bedeutet, dass wir jede Variable auf den kleinstmöglichen Bereich beschränken sollten, in dem sie benötigt wird. Variablen werden auch einfacher, wenn wir den Wert, den sie enthalten, nie ändern.
Eine sehr wichtige Metrik ist die zyklomatische Komplexität (McCabe-Komplexität). Es misst die Anzahl unabhängiger Pfade durch ein Stück Code. Diese Zahl wächst exponentiell mit jeder Bedingung. Jede Bedingung oder Schleife verdoppelt die Anzahl der Pfade. Es gibt Hinweise darauf, dass eine Punktzahl von mehr als 10 zu komplex ist. Dies bedeutet, dass eine sehr lange Funktion, die möglicherweise eine Bewertung von 5 hat, möglicherweise besser ist als eine sehr kurze und dichte Funktion mit einer Bewertung von 25. Wir können die Komplexität reduzieren, indem wir den Steuerungsfluss in separate Funktionen extrahieren.
Ihre Bedingung ist ein Beispiel für eine Komplexität, die vollständig extrahiert werden könnte:
function bigFatFunction(...) {
...
phoneNumber = getPhoneNumber(headers);
...
}
...
function getPhoneNumber(headers) {
return headers.resourceId ? headers.resourceId : DEV_PHONE_NUMBER;
}
Dies ist immer noch sehr nützlich. Ich bin nicht sicher, ob dies die Komplexität wesentlich verringert, da diese Bedingung nicht sehr bedingt ist . In der Produktion wird es immer den gleichen Weg nehmen.
Komplexität kann niemals verschwinden. Es kann nur herumgemischt werden. Sind viele kleine Dinge einfacher als wenige große? Das hängt sehr stark von den Umständen ab. Normalerweise gibt es eine Kombination, die sich genau richtig anfühlt. Um diesen Kompromiss zwischen verschiedenen Komplexitätsfaktoren zu finden, sind Fingerspitzengefühl, Erfahrung und ein bisschen Glück erforderlich.
Zu wissen, wie man sehr kleine und sehr einfache Funktionen schreibt, ist eine nützliche Fähigkeit, da Sie keine Wahl treffen können, ohne die Alternativen zu kennen. Das blinde Befolgen von Regeln oder bewährten Methoden, ohne darüber nachzudenken, wie sie auf die aktuelle Situation angewendet werden, führt bestenfalls zu durchschnittlichen Ergebnissen, im schlimmsten Fall zu Frachtkult-Programmen .
Dort bin ich nicht mit deinem Chef einverstanden. Seine Argumente sind nicht ungültig, aber auch das Clean Code-Buch ist nicht falsch. Es ist wahrscheinlich besser, die Richtlinien Ihres Chefs zu befolgen, aber die Tatsache, dass Sie über diese Probleme nachdenken und versuchen, einen besseren Weg zu finden, ist sehr vielversprechend. Wenn Sie Erfahrung sammeln, fällt es Ihnen leichter, ein gutes Factoring für Ihren Code zu finden.
(Hinweis: Diese Antwort basiert zum Teil auf Gedanken aus dem Blogbeitrag von Jimmy Hoffa über vernünftigen Code auf dem Whiteboard , der eine allgemeine Übersicht darüber bietet, was Code einfach macht.)