Archiv der Kategorie: Software Craftsmanship

Weiterbildung und meine Linkliste

Das stetige Lesen und Weiterbilden ist meiner Meinung nach maßgeblich, wer ein guter Softwareentwickler oder gar Software Craftsman sein möchte.

Auch wenn die Zeit dafür knapp ist, ist es äußerst wichtig, sich in gewisser Regelmäßigkeit Neuem und Anderem zu widmen.

Ich beispielsweise habe dafür immer den Sonntag Nachmittag gebucht. Hier versuche ich alle Themen, die ich unter der Woche so gesammelt habe, zu einem gewissen Teil abzuarbeiten. Ich habe mir dafür eine spezielle „Später ansehen“ Lesezeichen Liste angelegt, die ich ständig priorisiere und Sonntags dann versuche Top-Down abzuarbeiten.

Die Artikel oder Videos, welche ich besonders interessant finde, teile ich in der Regel über meinen Twitter-Account und in Zukunft auch hier auf meinem Blog. Dafür findet ihr oben in der Menü-Leiste die Rubrik „Links„, die ich stets aktualisieren möchte.

Mit meinem sonntaglichen Ritual bilde ich aber vorerst nur das Lesen und Anschauen von Blog-Posts, Fachartikeln und Fachvideos ab. Was mir noch fehlt ist eine gewisse Regelmäßigkeit zu entwickeln, sich sprachlich weiterzuentwickeln.

Gemeint sind hier natürlich nicht Deutsch oder Englisch, wobei man auch das tun kann :), sondern Programmiersprachen. Mir geht es hier vielmehr um das Vertiefen aktuell schon angewendeter Sprachen (bei mir Java) und das Erlernen neuer Sprachen. Aber auch das Erlenen von neuen Sprachfeatures, wie Lambdas in Java, stehen bei mir hoch im Kurs.

Momentan versuche ich kontinuierlich Codekatas, welche ich mir bei codewars.com raus suche, zu lösen und darüber meine Fähigkeiten zu verbessern. Damit lassen sich zwar ganz gut neue Sprachfeatures ausprobieren, aber ob ich damit eine Programmiersprache neu lernen könnte, hinterlässt bei mir noch ein wenig Skepsis.

Wie geht ihr damit um? Hinterlasst doch dafür einfach einen Kommentar oder schreibt mich auf Twitter an 🙂

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.