3 min

Folge 7: Code neu schreiben, Projekte weiterpflegen Pro-Grammierer-Podcast

    • Technology

Oft schaut man als Entwickler Code von früher an und fällt erst einmal aus allen Wolken: Dort ein Bug, dort schlechte Variablenbenennung, außerdem hat sich der Kunde beschwert, dass da etwas nicht funktioniert. Außerdem ist die Software-Architektur des Projekts nicht so ausgereift.

Dann überlegt man – wenn schon, dann richtig. Wäre es nicht einfach bessser, das Projekt noch mal neu zu starten und mit einem klar strukturierten Architektur anzufangen?

Kurze Antwort: Nein!

Lange Antwort: In jedem Projekt stecken, bis es wirklich funktioniert, tausende kleine Anpassungen. Natürlich gibt es eine optimale Systemarchitektur – quasi ein „Ideal“. Doch dieses Ideal erreicht man nicht, indem man das Projekt von vorn anfängt. Die Kosten dafür sind einfach zu hoch.

Was ist also die Alternative?

Die beste Lösung ist, das Projekt Stück für Stück auf die Zielarchitektur umzubauen. Dazu bedient man sich des Werkzeugkastens des „Refactorings“.

Denn Code hat immer 2 Dimensionen: Eine High-Level- und eine Low-Level-Dimension.

Arbeitet man auf der Low-Level-Dimension sauber, wird das Programm nicht abstürzen und sich in jeder erdenklichen Situation richtig verhalten. Außerdem stimmt dann auch die Performance.

Auf der High-Level-Ebene sind andere Dinge wichtig:
• Ist die Software auf mehreren Betriebssystemen lauffähig?
• Lässt sich die Software an neue Kundenbedürfnisse anpassen?
• Lässt sich die Software auch für andere und ähnliche Anwendungsfälle einsetzen?
• Lässt sich die Software gut von Menschen bedienen? UI-technisch
• Lässt sich die Software gut von Maschinen bedienen? Ich rede hier von API-Anbindung und ähnlichem

Einfache Bugs fixt man, indem man 1-2-3 Zeilen im Code abändert. High-Level-Änderungen benötigen oft Code-Anpassungen quer über das gesamte Projekt: Umbenennungen, neue Parameter in Interfaces, neue Aufteilung von Klassen….

Oberstes Ziel eines Refactoring sollte immer sein, so viel wie möglich Code zu entfernen, ohne die Funktion des Programms dabei einzuengen. Das bedeutet in erster Linie: Code Duplication aufspüren und anhand der gefundenen Duplikate verallgemeinern.

Oft ergeben sich durch diese Zusammenführung unterschiedlichster Code-Abschnitte zu Hilfsfunktionen ganz neue Sichtweisen auf das eigene Werk: Plötzlich muss man einen neuen Namen oder Begriff für eine Funktion finden, die zum Beispiel Angebote und Rechnungen gemeinsam haben. Was haben denn Angebote und Rechnungen gemeinsam? Sie besitzen beide eine Nummer aus einem Nummernkreis, sowie eine Liste von Positionen mit jeweils Bezeichnung, Menge und Preis. Doch die Struktur allein gibt uns noch keine guten Ideen für eine Benennung der Funktion.

Wir haben die Funktion am Ende „Vertriebsvorgänge“ genannt. Dazu zählen Angebote, Rechnungen, Lieferscheine, aber auch Einkäufe / Einkaufslisten. Allein die Benennung hat uns einen unheimlichen Schub an Ideen gegeben, was Vertriebsvorgänge eigentlich alles tun können.

Einmal deduplizierter Code ist awesome. Er lässt sich nicht nur an den 2 deduplizierten Stellen verwenden, sondern man findet in der Regel noch zig weitere Anwendungsfälle für allgemeinen Code.

Noch ein Nachtrag: Ich habe vorhin behauptet, High-Level-Code-Anpassungen erstrecken sich über das komplette Projekt. Das mag stimmen für traditionelle Programmiersprachen. Es gibt aber eine neuartige Programmiersprache namens FOP, bei der ist das etwas anders – zumindest für bestimmte Fälle. Bei der FOP-Programmiersprache kann man zum Beispiel in einem einfachen 5-Zeiler dafür sorgen, dass jede Funktion, in der PDFs generiert werden, eine Kopie des PDFs in einem Dokumentenmanagement ablegen. Wie genau diese Sprache solche abstrakten Anpassungen lokal halten kann, erfahrt ihr, wenn ihr den Podcast abonniert.

Oft schaut man als Entwickler Code von früher an und fällt erst einmal aus allen Wolken: Dort ein Bug, dort schlechte Variablenbenennung, außerdem hat sich der Kunde beschwert, dass da etwas nicht funktioniert. Außerdem ist die Software-Architektur des Projekts nicht so ausgereift.

Dann überlegt man – wenn schon, dann richtig. Wäre es nicht einfach bessser, das Projekt noch mal neu zu starten und mit einem klar strukturierten Architektur anzufangen?

Kurze Antwort: Nein!

Lange Antwort: In jedem Projekt stecken, bis es wirklich funktioniert, tausende kleine Anpassungen. Natürlich gibt es eine optimale Systemarchitektur – quasi ein „Ideal“. Doch dieses Ideal erreicht man nicht, indem man das Projekt von vorn anfängt. Die Kosten dafür sind einfach zu hoch.

Was ist also die Alternative?

Die beste Lösung ist, das Projekt Stück für Stück auf die Zielarchitektur umzubauen. Dazu bedient man sich des Werkzeugkastens des „Refactorings“.

Denn Code hat immer 2 Dimensionen: Eine High-Level- und eine Low-Level-Dimension.

Arbeitet man auf der Low-Level-Dimension sauber, wird das Programm nicht abstürzen und sich in jeder erdenklichen Situation richtig verhalten. Außerdem stimmt dann auch die Performance.

Auf der High-Level-Ebene sind andere Dinge wichtig:
• Ist die Software auf mehreren Betriebssystemen lauffähig?
• Lässt sich die Software an neue Kundenbedürfnisse anpassen?
• Lässt sich die Software auch für andere und ähnliche Anwendungsfälle einsetzen?
• Lässt sich die Software gut von Menschen bedienen? UI-technisch
• Lässt sich die Software gut von Maschinen bedienen? Ich rede hier von API-Anbindung und ähnlichem

Einfache Bugs fixt man, indem man 1-2-3 Zeilen im Code abändert. High-Level-Änderungen benötigen oft Code-Anpassungen quer über das gesamte Projekt: Umbenennungen, neue Parameter in Interfaces, neue Aufteilung von Klassen….

Oberstes Ziel eines Refactoring sollte immer sein, so viel wie möglich Code zu entfernen, ohne die Funktion des Programms dabei einzuengen. Das bedeutet in erster Linie: Code Duplication aufspüren und anhand der gefundenen Duplikate verallgemeinern.

Oft ergeben sich durch diese Zusammenführung unterschiedlichster Code-Abschnitte zu Hilfsfunktionen ganz neue Sichtweisen auf das eigene Werk: Plötzlich muss man einen neuen Namen oder Begriff für eine Funktion finden, die zum Beispiel Angebote und Rechnungen gemeinsam haben. Was haben denn Angebote und Rechnungen gemeinsam? Sie besitzen beide eine Nummer aus einem Nummernkreis, sowie eine Liste von Positionen mit jeweils Bezeichnung, Menge und Preis. Doch die Struktur allein gibt uns noch keine guten Ideen für eine Benennung der Funktion.

Wir haben die Funktion am Ende „Vertriebsvorgänge“ genannt. Dazu zählen Angebote, Rechnungen, Lieferscheine, aber auch Einkäufe / Einkaufslisten. Allein die Benennung hat uns einen unheimlichen Schub an Ideen gegeben, was Vertriebsvorgänge eigentlich alles tun können.

Einmal deduplizierter Code ist awesome. Er lässt sich nicht nur an den 2 deduplizierten Stellen verwenden, sondern man findet in der Regel noch zig weitere Anwendungsfälle für allgemeinen Code.

Noch ein Nachtrag: Ich habe vorhin behauptet, High-Level-Code-Anpassungen erstrecken sich über das komplette Projekt. Das mag stimmen für traditionelle Programmiersprachen. Es gibt aber eine neuartige Programmiersprache namens FOP, bei der ist das etwas anders – zumindest für bestimmte Fälle. Bei der FOP-Programmiersprache kann man zum Beispiel in einem einfachen 5-Zeiler dafür sorgen, dass jede Funktion, in der PDFs generiert werden, eine Kopie des PDFs in einem Dokumentenmanagement ablegen. Wie genau diese Sprache solche abstrakten Anpassungen lokal halten kann, erfahrt ihr, wenn ihr den Podcast abonniert.

3 min

Top Podcasts In Technology

The CEDIA Podcast
Walt Zerbe
All-In with Chamath, Jason, Sacks & Friedberg
All-In Podcast, LLC
Darknet Diaries
Jack Rhysider
This Week in Startups
Jason Calacanis
Hot Girls Code
Hot Girls Code
Security Now (Audio)
TWiT