Eines der grundlegenden Prinzipien in der Softwareentwicklung ist das KISS-Prinzip: In der Formulierung Keep it simple, stupid ist im roten Grad von Clean Code Developer (CCD) enthalten, Extreme Programming propragiert Einfachheit als Regel und auch im Agilen Manifest ist Einfachheit als essenzielles Prinzip enthalten.
Softwareentwicklung soll sich also an Einfachheit orientieren – doch was bedeutet das? Was gilt als einfach und was nicht?
Eine eindeutige und allgemein akzeptierte Definition erscheint schwierig, entsprechend verschieden fallen die jeweiligen Erklärung auch aus. Während es auf der CCD-Webseite zunächst
Wer mehr tut als das Einfachste, lässt den Kunden warten und macht die Lösung unnötig kompliziert.
heißt, was sich mit dem im blauen Grad enthaltenen YAGNI-Prinzip überschneidet, wird dann im weiteren Text jedoch erläutert, es sei
für die Evolvierbarkeit des Codes zwingende Voraussetzung, dass der Code verständlich sei.
Zwar ist verständlich ein ebenso subjektiver Begriff wie einfach, deutet aber schon eher in die gewünschte Richtung. Verständlichkeit war auch das Ziel, das ich in meinem Blogeintrag Anmut und Eleganz verfolgt habe – insofern ziehen CCD und ich hier an einem Strang.
Schön ist, dass CCD dabei auch auf Code zu sprechen kommt:
Wenn ein IEnumerable reicht, sollte kein ICollection oder sogar IList verwendet werden.
Auch das entspricht meiner Vorstellung und deckt sich mit dem, was ich als eine gelungene innere Form von Code bezeichne.
XP nennt ebenfalls Verständlichkeit, allerdings nur als einen von vier Aspekten, die gemeinsam Einfachheit definieren. Nach XP zählen hierzu noch die drei Aspekte Testbarkeit, Navigierbarkeit und Erklärbarkeit:
- Testbarkeit: Nur Code, der sich auf das Notwendige beschränkt, ist zugleich auch einfach zu testen – ansonsten müssen nämlich Spezial- und Sonderfälle wie auch die Auswirkungen von Seiteneffekten im Test berücksichtigt werden. Auch wenn weder CCD noch ich in Anmut und Eleganz die Testbarkeit explizit im Zusammenhang mit Einfachheit ansprechen – auch hier sind wir letztlich einer Meinung.
- Navigierbarkeit: Zur Einfachheit von Code zählt neben einer guten Verständlichkeit und einer guten Testbarkeit auch eine gute Navigierbarkeit: Das heißt, in einfachem Code findet man sich zurecht, und es fällt leicht, zwischen den beteiligten Klassen und Komponenten hin und her zu navigieren.
- Erklärbarkeit: Während die Testbarkeit in gewissem Sinne messbar ist, sind Einfachheit und Navigierbarkeit in höchstem Maße subjektiv: Negativ fällt dies vor allem dann auf, wenn ein Team eingespielt ist und bereits lange Zeit an einer Software arbeitet – in diesem Fall wird sich jeder Entwickler des Teams im Code zurechtfinden und ihn verstehen. Aus diesem Grund muss Code für Einfachheit zusätzlich auch einem Uneingeweihten einfach zu erklären sein.
Das Agile Manifest schließlich definiert Einfachheit als
the art of maximizing the amount of work not done.
Hier wird also letztlich nur der Effekt der Reduktion, des minimalen Codes betont – was jedoch für mein Empfinden nicht genügt. Sicherlich kann man argumentieren, dass in dieser Aussage implizit auch die Arbeit angesprochen wird, die zum späteren Verstehen von Code investiert werden muss – viele Entwickler werden diese Interpretation jedoch zunächst überlesen.
All zu oft wird Einfachheit ansonsten nämlich mit dem YAGNI-Prinzip gleichgesetzt – dabei handelt es sich jedoch um zwei verschiedene Konzepte: Das YAGNI-Prinzip empfiehlt, keine Funktionalität im guten Glauben auf die zukünftige Erforderlichkeit umzusetzen, ohne eine konkrete Anforderung dafür zu haben. Das ist dann auch genau das, was im Rahmen von CCD kritisiert wird:
Wer mehr tut als das Einfachste, lässt den Kunden warten und macht die Lösung unnötig kompliziert.
Einfachheit im Sinne des KISS-Prinzips läuft jedoch Gefahr, dass während der Entwicklung lediglich simple und naheliegende Sprachkonstrukte verwendet werden – obwohl ein fortgeschritteneres Konstrukt eventuell deutlich besser geeignet wäre. Ein typisches Beispiel hierfür ist das Schlüsselwort yield, das viel zu selten Verwendung findet.
Außerdem wird dabei häufig auf Design für zukünftige Erweiterbarkeit verzichtet, obwohl dies mit nur unwesentlich mehr Aufwand möglich wäre – so wird beispielsweise eher auf verschachtelte und zahlreiche if-Anweisungen statt auf besserpassende objektorientierte Konstrukte gesetzt.
Kurzum: Einfachheit bedeutet nicht zwingend, das Naheliegendste und mit möglichst wenig Aufwand umsetzbare zu implementieren, sondern erstens, keine Funktionalität zu entwickeln, für die keine Anforderung besteht, zweitens, der Verständlichkeit des Codes höheren Stellenwert einzuräumen als der Entwicklung, und drittens, die zukünftige Erweiterbarkeit nicht außer Acht zu lassen.
Schlussendlich kann man daher festhalten, dass der Begriff einfach nicht besonders glücklich gewählt ist: Häufig wird darunter nämlich die minimalistische Reduktion auf einfache Sprachkonstrukte und wenige Codezeilen verstanden – die Verständlichkeit und zukünftige Erweiterbarkeit bleiben hierbei außen vor.
Daher wäre es meines Erachtens sinnvoll, an Stelle von Einfachheit – oder zumindest zusätzlich – einen anderen, treffenderen Begriff zu propagieren, der Verständlichkeit und zukünftige Erweiterbarkeit einschließt. Am ehesten treffen dies meiner Meinung nach die Begriffe Anmut und Eleganz.