© Excellent backgrounds/Shutterstock.com
Eine Typologie für Softwareentwickler

Design Types


„Das hätte ich anders gemacht“ ist eines der häufigsten Zitate oder Denkweisen, die genau dann auftreten, wenn ein Softwareentwickler den Code eines Kollegen inspiziert. Und das selbst in Zeiten, in denen einheitliche Code-Formater und Quellcodequalitätsmetriken immer häufiger eingesetzt werden. Fernab von Syntaxoptimierung und Vereinheitlichung gibt es wohl doch noch elementare Unterschiede in der Art und Weise, wie Individuen Lösungen gestalten.

Doch woran liegt das? Zum einen ist die Softwareentwicklung (glücklicherweise) immer noch ein kreativer Beruf und bietet somit persönlichen Gestaltungsspielraum, den eine Henne in einer Legebatterie nicht mehr hat. Zum anderen gibt es oft verschiedene Wege, die man einschlagen kann, um das geforderte Ziel zu erreichen. Es gibt zwar sicherlich auch falsche Wege, aber ebenso gibt es auch viele unterschiedliche Wege, die zum Erfolg führen.

Und auf dem Weg zum Ziel treffen wir täglich viele Designentscheidungen: Das fängt bei kleinen Dingen wie einer Methodensignatur an, beinhaltet aber ebenso die Verwendung bestimmter Sprachfeatures oder zusätzlicher Bibliotheken. Aber auch die Art und Weise, wie eine Schnittstelle oder ein API designt ist oder welche Designprinzipien oder Design Patterns zur Anwendung kommen, zählt neben vielem anderen mit dazu.

Jeder Entwickler hat, basierend auf seinen Erfahrungen, ein eigenes Wertesystem für gutes und schlechtes Softwaredesign und entwickelt dieses meist kontinuierlich weiter. Man kann hier durchaus vom „Programmierstil“ sprechen. Da wir darin aber mehr sehen als nur den syntaktischen Aufbau von Quellcode, beinhaltet dieser auch das Wertesystem für Softwaredesign. Und diese beiden Teile zusammen sind oft die Messlatte, anhand derer die „Qualität“ oder „Reife“ des eigenen Quellcodes bemessen wird.

Dasselbe Wertesystem wird natürlich auch auf die Erzeugnisse anderer Kollegen angewendet (oft auch ein wenig strenger, da man sich selbst oft mehr Freiräume zugesteht). Und da es menschlich ist, dass man sich auch immer wieder mit anderen vergleicht, wird anhand des eigenen Wertesystems bemessen, ob der Kollege gute oder schlechte Arbeit abgeliefert hat. Nicht selten kommt dann etwa der Satz: „Das hätte ich anders gemacht“, vielleicht noch in der wertschätzenden Variante: „Das kann man schon so machen, ich hätte das aber ein wenig anders gemacht.“

Die wesentliche Frage, die sich hier aber geradezu aufdrängt, lautet „Warum hättest du es anders gemacht?“ Und genau das ist der Punkt, der die Kommunikation zwischen Entwicklern schwierig machen kann: „Wie erklärt man das?“

Gehen wir mal davon aus, dass beide Designentscheidungen keine offensichtlichen Fehler beinhalten. Dann mündet die anschließende Diskussion darüber, welche davon umgesetzt werden soll, oft in einer unbefriedigenden, manchmal auch religiösen Diskussion, die dann kein vernünftiges Ergebnis hervorbringt. Und Sätze wie „das hat meine Erfahrung gezeigt“ oder „das machen wir jetzt so, da wir eh keine Zeit haben es anders zu machen“ werden zwar gelegentlich angewandt, sind aber für denkende Menschen nicht überzeugend, geschweige denn zielführend.

Vier Dimensionen mit jeweils zwei Ausprägungen

Aber wie schafft man es nun, mit dem Kollegen auf einer für beide Seiten verständlichen Basis sachlich und objektiv zu diskutieren? Letztendlich beruht doch jede Argumentation auf ihren entsprechenden Argumenten, die aufgeführt und entsprechend bewertet werden können. Um diese Argumente (oder besser Beweggründe) besser einordnen zu können, haben wir vier Dimensionen definiert. Jede dieser Dimensionen unterteilt sich in genau zwei unterschiedliche bzw. konträre Ausprägungen.

Nehmen wir als Beispiel die oben genannte Henne aus der Legebatterie, die wir implementieren sollen, um diese in einer Simulation eines Legebatteriebetriebs nutzen zu können. Konkret wird von einer Henne erwartet, dass diese pro Tag zwei bis vier Eier legt. Listing 1 zeigt eine mögliche Implementierung der Aufgabenstellung. In der Tat ist die Aufgabe, gelinde gesagt, sehr einfach umgesetzt. Listing 2 zeigt eine alternative Variante. Hier kann man erkennen, dass bereits viele Möglichkeiten berücksichtigt wurden. Es wurde verallgemeinert, sodass diese Lösung einfach erweitert werden kann z. B. für Wachteln. Außerdem wurde bereits ein flexibler und erweiterbarer Algorithmus definiert, der den Output an Eiern bestimmt.

Listing 1

public class Hen { private int minimumEggs; private int maximumEggs; public Hen(int minimumEggs, int maximumEggs) { this.minimumEggs = minimumEggs; this.maximumEggs = maximumEggs; } public int layEggs() { int range = this.maximumEggs - this.minimumEggs; int intInRange = (int) Math.round(Math.random() * range); return (intInRange + this.minimumEggs); } }

Listing 2

public abstract class Bird { public abstract Range<Integer> getHereditaryLayingRange(); public abstract Properties getProperties(); public abstract Egg produceEgg(); // factory method public List<Egg> layEggs(InfluencingFactor... factors) { List<Egg> eggs = new LinkedList<Egg>(); Range<Integer> curRange = getHereditaryLayingRange(); BigDecimal minValue = new BigDecimal(curRange.getMinimum()); BigDecimal maxValue = new BigDecimal(curRange.getMaximum()); for (InfluencingFactor influencingFactor : factors) { float shiftMin = influencingFactor.getShiftForMinimum(getProperties()); minValue = minValue.add(BigDecimal.valueOf(shiftMin)); float shiftMax = influencingFactor.getShiftForMaximum(getProperties()); maxValue = maxValue.add(BigDecimal.valueOf(shiftMax)); } minValue = minValue.setScale(1, BigDecimal.ROUND_HALF_UP); maxValue = maxValue.setScale(1, BigDecimal.ROUND_HALF_UP); BigDecimal pointInRange = maxValue.subtract(minValue).multiply(new BigDecimal(Math.random())); pointInRange = pointInRange.setScale(0, BigDecimal.ROUND_HALF_UP); int amountEggs = minValue.add(pointInRange).intValue(); while (amountEggs > 0) { eggs.add(produceEgg()); amountEggs--; } return eggs; } } public class Hen extends Bird { private Range<Integer> layingRange; private Properties properties; public Hen(Integer minimumEggs, Integer maximumEggs, Properties properties) { this.layingRange = Range.between(minimumEggs, maximumEggs);...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang