Schlagwort-Archive: Software Design

Der Wendepunkt

Wie entscheiden wir, wie weit wir gehen müssen, um eine bestimmte Anforderung an unsere Software zu erfüllen und wie wir diese implementieren?

Ist der einfachste Weg hier der richtige oder wäre der simpelste besser? Was genau macht den Unterschied aus?

Mit diesen Fragen beschäftigt sich Sandro Mancuso in einem Blogbeitrag, den ich gerne zusammenfassen möchte.

Es gibt immer einen Punkt, an dem wir uns entscheiden, wo in unserem System wir Änderungen implementieren, die dann zum gewünschten, neuen Verhalten führen. Manche würden dafür exakt nur genauso viel Code schreiben, um der Anforderung/Verhalten zu genügen. Dieser Ansatz wird stark durch TDD getrieben und unterstützt. Andere schreiben deutlich mehr Code als gefordert, um vielleicht zukünftige Anforderungen mit abzudecken. Auch hier wird man prima durch TDD unterstützt, nur ist die Frage, wie weit sollte man sich von der Anforderung (in die Zukunft) entfernen? Kann man diese überhaupt vorhersagen? Wird dadurch unter Umständen die Anwendung nicht unnötig komplexer?

„Der Anspruch, eine Anwendung so flexibel für ihren Gesamten Lebenszyklus zu schreiben, dass Änderungen am Verhalten oder den Anforderungen an die Software leicht zu implementieren wären, ist schlicht unmöglich. Man wird es immer falsch machen, egal was man unternimmt“.

Dieser These kann ich mich nur anschließen.

Sandro beschreibt das Problem mit dem Begriff „Inflection Point“, welchen er wie folgt definiert:

„Der Inflection Point definiert den maximalen Aufwand, den wir mit Gutem Gewissen aufbringen können (um dem neuen Verhalten zu genügen), um den gewünschten Grad an Flexibilität zu erreichen, den wir zum aktuellem Moment benötigen. Alles was hinter diesem Inflection Point liegt, ist den Aufwand nicht wert.“

Wie aber nähert man sich diesem Punkt? Entweder von rechts nach links, oder von links nach rechts.

Wenn wir uns von Rechts dem Inflection Point nähern, dann betrachten wir die Features unserer Software, die wir in näherer Zukunft umsetzen wollen. Wir denken also darüber nach, wie die ideale Lösung für unsere Features aussehen würden. Von diesem Punkt aus wandern wir weiter Richtung links und überlegen uns, wie wir die Lösung günstiger bzw. schneller implementieren könnten, ohne dabei die Flexibilität für die zukünftigen Features aus dem Auge zu verlieren. Irgendwann werden wir unsere Lösung aber immer so weit vereinfacht haben (um sie auch schneller umsetzen zu können), dass wir zu viel Flexibilität verlieren würden, um noch unserer idealen Lösung für das Feature (und zukünftige) zu genügen. Änderungen würden hier einfach wieder zu „teuer“ werden. Sobald man an diesem Punkt angekommen ist, hat man den Inflection Point von der rechten Seite aus erreicht.

Von der linken Seite aus ist man bestrebt, eine Lösung so schnell und einfach wie möglich umzusetzen, um den Anforderungen eines neue Features/Verhalten zu genügen. Wobei hier ausdrücklich nicht Quick-and-Dirty gemeint ist. Erst dann würden wir anfangen über direkt im Anschluss anstehende Features und über die potenziellen Möglichkeiten unserer Software in der näheren Zukunft nachzudenken. Dadurch sind wir in der Lage zu entscheiden, wie flexibel unser aktueller Code gegenüber der Zukunft überhaupt sein muss. Stellen wir Fest, dass wir unseren Code so weit flexibel halten wollen, dass er zu aufwändig zu Implementieren wäre, dann haben wir den Inflection Point von der linken Seite aus erreicht.

Für mich hat der erste Ansatz (von rechts nach links) einen starken Character von Over-engineering. Dies führt zu erheblichen Kosten im Bereich der Wartung der Software und letztendlich leidet darunter auch die Flexibilität, die man sich zu erst noch auf die Fahnen geschrieben hat.

Sich im Voraus Gedanken über die zukünftigen Features einer Software zu machen ist selbstverständlich nicht falsch, nur bin ich der Meinung, dass diese nicht das Design direkt beeinflussen sollten. Natürlich kann man an manchen Stellen versuchen, die Software für anstehende Features flexibel zu halten, aber man sollte dies stets mit dem zu erbringenden Aufwand abwägen. Daher würde ich dem Ansatz, sich von links dem Inflection Point zu nähern, häufiger den Vorzug geben. In einem Entwicklungsteam bietet dieser Ansatz auch verstärkt die Möglichkeit, nach jedem Schritt zu reflektieren und den Plan für das weitere Vorgehen neu festzulegen.