Konstruktionsprinzipien
In allen technischen Disziplinen hängt es maßgeblich von der Qualität des gewählten
Designs ab, wie gut eine geplante Konstruktion
später realisiert werden kann. Physikalische Grenzen für Konstruktionen haben in der
Software-Entwicklung eine
geringere Bedeutung verglichen mit anderen Bereichen wie beispielsweise dem Bauwesen.
Einzelne Verstöße gegen Regeln für gutes Design
werden das Ergebnis nicht sofort spürbar beeinträchtigen. Aus langfristiger Sicht
addieren sich die Probleme allerdings.
Unsere Überlegungen dazu haben wir in den nachfolgenden Abschnitten dieser Seite beschrieben
und grafisch veranschaulicht. Aufgrund
der gebotenen Kürze lassen wir erst einmal offen, über welche Granularität einer Konstruktion
wir sprechen. Die notwendige
Differenzierung dazu erfolgt in unserem abschließenden Fazit.
Monolithische Konstruktion
Für unsere beispielhafte Betrachtung soll die monolithische Konstruktion primär zwei
Aspekte verdeutlichen:
Bei der Betrachtung des abgebildeten Beispiels fällt sofort auf, wie schwierig es
wäre, die Position der Tür nachträglich
noch zu verändern. In manchen eng abgegrenzten Anwendungsfällen besteht allerdings
auch kein Änderungsbedarf, und unter
solchen Umständen ist der monolithische Ansatz auch vertretbar, weil man durch den
Verzicht auf Variabilität Aufwand einspart.
Weiß man hingegen noch nicht genau, wie stark sich die Anforderungen an den geplanten
Bau später einmal verändern werden, ist
eine modulare Konstruktion der monolithischen vorzuziehen.
Modulare Konstruktion
Wesentlich mehr Flexibilität als der vorgestellte Monolith verspricht eine Konstruktion
aus modularen Elementen. Das nachstehende
Beispiel soll folgende Aspekte illustrieren:
Im dargestellten Beispiel unterscheiden sich die Elemente abhängig von ihrer konkreten
Funktion (Dach, Wände, Rahmen).
Idealerweise behalten sie trotzdem eine gewisse Unabhängigkeit: Die Bretter auf dem
Dach könnten vom Prinzip her auch an
ganz anderer Stelle eingesetzt werden, ebenso die Rahmenelemente für Tür und Fenster.
Wichtige Indikatoren dafür, ob eine Konstruktion als gelungen betrachtet werden darf,
sind u.a. folgende:
- Konstruktionselemente werden nach einem durchgängigen Prinzip eingesetzt, für das
im Idealfall keine Ausnahmen gelten.
-
So wie die verschiedenen Elemente verwendet wurden, repräsentieren sie auch eine Bedeutungsebene
(etwas gehört entweder zum Dach,
zur Wand oder zu einem Tür- bzw. Fensterstock - im Gegensatz zu "wir können nicht
genau sagen, welche Funktion dieses Element übernimmt").
Welche Vorteile sich ganz allgemein aus einer gelungenen Konstruktion ergeben, erschließt
sich am deutlichsten, wenn man sich Gegenbeispiele
vor Augen führt wie die verwobene Konstruktion im nächsten Abschnitt.
Verwobene Konstruktion
Im hier betrachteten Kontext stellt es keinen Vorteil dar, wenn alles miteinander
vernetzt und verwoben ist, sondern ein Problem: Aufgrund
der starken Wechselwirkung zwischen den meisten Elementen der Konstruktion haben selbst
kleine Änderungen große Auswirkungen. Dazu kommt
noch ein weiterer Nachteil: Rein auf analytischem Wege, also ohne etwas auszuprobieren,
lassen sich kaum Aussagen darüber machen, welche
Elemente wie stark mit anderen wechselwirken. Darunter leidet besonders die Planbarkeit
der Umsetzung neuer Anforderungen.
In Anlehnung an den Begriff "Monolith" (monos = einzeln, Lithos = Stein) führen wir
für eine Konstruktion wie die vorliegende den Begriff
"Heteroxyl" ein. Ein solches besteht nicht nur aus einem einzelnen Grundelement, sondern
aus mehreren verschiedenartigen ("heteros"), und
es besteht nicht aus Stein, sondern aus Holz ("Xylon").
In der Praxis der Software-Entwicklung treten Heteroxyle viel häufiger auf als man
es erwarten würde. Oft entstehen sie aus einem eher
zufälligen ersten Entwurf, der überraschend erfolgreich war. Anstatt ausgehend von
einem solchen spontanen Ansatz eine reguläre, solide
Konstruktion zu entwickeln, lässt man sich vom Trugbild des bereits erzielten Erfolges
leiten und verzichtet auf eine gründliche
Rekonstruktion – wohl aus der Angst heraus, etwas bereits Funktionierendes aufzugeben.
Je mehr schon in ein Heteroxyl investiert wurde, desto schwerer kann man sich später
wieder von ihm trennen. In der Praxis stößt man daher
selten auf Heteroxyle im Rohzustand wie oben, sondern meist auf begradigte Varianten,
die schon viel Pflege erfahren haben:
Im hier skizzierten Beispiel wurden gegenüber dem vorherigen Zustand die allzu auffälligen
Überstände entfernt. Außerdem wurden die linke
und rechte Ecke der Behausung mit markanten Pfosten versehen, und im Dachbereich wurden
einige der besonders unhandlichen Elemente
durch kleinere ersetzt. Selbst wenn man einer solchen Konstruktion eine minimale Entwicklung
attestieren darf, bleibt
sie aus verschiedenen Gründen immer noch problematisch:
- Die vorgenommenen Änderungen haben vermutlich hohen Aufwand verursacht. Trotzdem wird
man kaum von einem technologischen Durchbruch
sprechen wollen. Der Aufwand für zukünftige Änderungen wird weiter ansteigen.
- Die Wechselwirkungen der Elemente untereinander sind immer noch komplex und kaum einschätzbar.
-
Nach wie vor bleibt die logische Bedeutung einzelner Elementverbünde unklar: Welche
Elemente stehen genau wofür? Wollte man beispielsweise die
Tür nachträglich verbreitern, müsste man erst einmal mit einigem Aufwand bestimmen,
welche Elemente als zum Türbereich gehörig betrachtet werden
sollen - denn die Rolle eines jeweiligen Elements kann nicht aus der Konstruktion
selbst abgeleitet werden.
Ein Heteroxyl ist trotz seiner gegebenen Schwächen flexibler als ein Monolith und
lässt sich daher auch einfacher ändern oder erweitern –
zumindest vom Prinzip her. In der Praxis werden jedoch selbst geringfügige Modifikationen
die Stabilität der gesamten Konstruktion
beeinträchtigen. Jede heteroxylotische Komponente stellt daher ein allgegenwärtiges
Risiko für das gesamte Software-System dar, in das sie
eingebettet ist: Der Aufwand für Änderungen lässt sich ähnlich schwer einschätzen
wie die Auswirkungen von Änderungen auf das restliche
System.
Prototypische Konstruktion
Was genau soll eigentlich gebaut werden, damit sich später der erhoffte Nutzen einstellt?
Diese Herausforderung besteht auch beim Aufbau
einer modularen Konstruktion, denn es muss zumindest vorab entschieden werden, mit
welchen unterschiedlichen Typen von Elementen gebaut
werden soll. Um den praktischen Nutzen einer geplanten Entwicklung schon vor ihrer
endgültigen Realisierung abschätzen zu können, ist
es meist sinnvoll, mit einem Prototyp zu beginnen.
Hinter dem Bau eines Prototypen steckt die Idee, gegenüber der endgültigen Realisierung
durch gezielte Vereinfachungen konstruktiven
Aufwand einzusparen. Trotzdem möchte man dabei aber zu einem Ergebnis zu kommen, das
vom Nutzwert her möglichst direkt der eigentlich geplanten
Konstruktion entspricht. Das abgebildete Beispiel für eine prototypische Behausung
besteht aus Zweigen, die aus sich allein
heraus nicht genügend tragfähig wären. Sie wurden daher mit Lehm verputzt, was dem
gesamten Gebilde Stabilität gibt. Durch die Dichtheit
der Konstruktion können alle jene Fragen mit hinreichender Genauigkeit beantwortet
werden, die für einen Prototyp dieser Art sinnvoll
gestellt werden können:
Bei einer realen Lehmkonstruktion ließe sich beispielsweise schon an Materialwahl
sowie Art der Verarbeitung erkennen, ob die Konstruktion
aufgrund geringer Wetterfestigkeit nur prototypischen Charakter hätte. In der Software-Entwicklung
hingegen bemisst sich die langfristige
Eignung einer Konstruktion unter anderem an folgenden Kriterien:
Bewertet man die oben abgebildete Konstruktion anhand der genannten Kriterien, so
würde man sie als Prototyp bezeichnen, schon allein
deswegen, weil der Lehmputz den Blick auf das Holzskelett verwehrt und somit der gesamte
Aufbau nur schlecht nachvollziehbar ist. Aufgrund
der dünnen verwendeten Streben müsste man generell davon ausgehen, dass die Tragfähigkeit
nur geringe Reserven bietet. Somit lässt sich
vorab kaum erkennen, welches Limit für die Belastung tatsächlich besteht, oder an
welchen Stellen beispielsweise
gefahrlos Durchbrüche möglich wären.
In bestimmten Punkten ähnelt eine prototypische Konstruktion mehr dem Monolithen,
in anderen wiederum eher dem Heteroxyl. Die praktischen
Nachteile aus dieser Verwandschaft sind jedoch zu vernachlässigen, da der Prototyp
mit Absicht leichtgewichtig und reduziert angelegt wurde:
Insgesamt ergibt sich für den Aufbau eines Prototypen ein wesentlich geringerer Aufwand
als für andere Konstruktionen vergleichbaren
Umfangs. Sollten nachträglich wider Erwarten doch größere Änderungen erforderlich
werden, konstruiert man am besten einen neuen Prototyp.
Fazit
In den vorangegangen Abschnitten wurden verschiedene Ansätze für technische Konstruktionen
miteinander verglichen: Monolith, modulare
Konstruktion, verwobene Konstruktion und Prototyp. Ausgangspunkt für unsere Überlegungen
war die Frage, warum sich Software in der Praxis
oft in eine so unvorteilhafte Richtung hin entwickelt. Bevor wir darauf Antworten
geben, wollen wir die bisher skizzierten Modelle noch
so weit verfeinern, dass klar wird, welche Aspekte uns jeweils besonders wichtig sind.
Differenzierte Bewertung
Wie schon ganz zu Beginn unseres Artikels angedeutet, gelten Nachteile und Vorzüge
der verschiedenen Ansätze für Konstruktionen immer nur
innerhalb gewisser Grenzen. So ist gegen ein monolithisches Modul nichts einzuwenden,
sofern es sich auf einen überschaubaren Bereich von
Funktionalität beschränkt. Letztlich mündet jegliche Abbildung der realen Welt durch
Software irgendwann in eine Sequenz aus
Programmschritten, die möglichst direkt einen bestimmte Teil der Anforderungen widerspiegeln
– bis hinunter zu einzelnen Zeilen
Programmcode, die dann spätestens als monolithisch zu betrachten sind. Sobald sich
die Anforderungen einmal ändern, müssen genau
diese Bestandteile des Systems ersetzt werden – was problemlos gelingt, solange die
monolithischen Anteile kompakt und frei von
unübersichtlichen Wechselwirkungen bleiben.
Auch für eine verwobene Konstruktion gilt Analoges: In einem vertretbaren Umfang kann
sie der Aufgabenstellung entsprechen.
Zum Heteroxyl mit allen daraus resultierenden Nachteilen wird eine Konstruktion erst
dann, wenn ihre Vernetzung ein noch gut
beherrschbares Ausmaß überschritten hat.
Selbst das eigentlich favorisierte Prinzip der modularen Konstruktion ist nicht uneingeschränkt
vorteilhaft. In dem von uns gewählten
Beispiel könnte man auf den Gedanken verfallen, anstelle der spezialisierten Elemente
für die Wandbalken, Dachlatten und Rahmenteile eine
weitere Ebene der Modularität einzuführen mit dem Ziel, auch die speziellen Elemente
selbst aus noch allgemeineren aufzubauen. Man darf
jedoch vermuten, dass die Relation von Aufwand zu Nutzen in diesem Gedankenexperiment
gegenüber der direkten Konstruktion der Basiselemente
sehr schlecht ausfallen dürfte: Jede zusätzliche Ebene steigert automatisch die Komplexität
einer Gesamtkonstruktion. Außerdem sind
Abstraktionen nur so lange gut nachvollziehbar, wie sie sich eine gewisse Anschaulichkeit
bewahrt haben. Insofern ist es generell ratsam,
Generik und Indirektionen nur in Bereichen einzusetzen, wo man das auch inhaltlich
erwarten würde.
Eine prototypische Konstruktion schließlich steht dafür, dass ein Teil der bekannten
Anforderungen bewusst nicht erfüllt wird. Das ist
solange legitim, wie der Prototyp nicht über seinen anfangs geplanten Umfang hinaus
beansprucht wird.
Aus dieser Differenzierung folgt erst einmal, dass es keine einfachen Patentrezepte
gibt, deren Einhaltung automatisch gute Ergebnisse bei
der Realisierung einer komplexen Konstruktion garantiert. Bei näherer Betrachtung
fällt auf, dass fast alle Ansätze ihre jeweils
spezifische Berechtigung haben – bis auf die zum Heteroxyl degenerierte Konstruktion.
Man kann daher vermuten, dass Heteroxyle entweder
unabsichtlich entstehen oder dass sie vielleicht anfangs noch für etwas Ungefährliches
oder gar Nützliches gehalten werden. Hieraus ergeben
sich die folgenden Fragen:
Entstehung von Heteroxylen
Zuallererst benötigt man Kriterien, um ein Heteroxyl zuverlässig zu identifizieren.
Hierzu kann man sich zwei der schon vorgestellten
Beispielillustrationen noch einmal vor Augen führen:
Bei der modularen Konstruktion fällt auf, dass ihre Grundelemente ein hohes Maß an
Ausarbeitung aufweisen. Dadurch ermöglichen sie einen
präzisen Aufbau, egal wofür genau sie eingesetzt werden. Letztlich resultiert auch
die beabsichtigte Flexibilität der Konstruktion aus der
Qualität ihrer Grundelemente.
Beim Heteroxyl hingegen wurde die Ausarbeitung der Elemente auf ein Minimum beschränkt,
indem mehr oder weniger zufällig Vorhandenes
praktisch im Rohzustand eingesetzt wurde. Man hat sich also in seinem Design zu wenig
vom Vorhandenen (den frisch geschlagenen Baumstämmen)
gelöst und kann sich deswegen auf konstruktiver Ebene nicht mehr adäquat ausdrücken.
Ein Anreiz für diesen letztlich trügerischen Weg, Aufwand zu sparen, mag der Gedanke
sein, "nur erst einmal" direkt auf das faktische Ziel
einer Entwicklung hin zu arbeiten und die nötigen Versäuberungen "später" (falls überhaupt)
nachzureichen, wenn man bereits ein
greifbares Ergebnis in der Hand hat. Genau dieses Vorgehen wird jedoch sicher nicht
von Erfolg gekrönt sein:
- Die unausgearbeiteten Elemente der Konstruktion lassen sich nur in einer Weise verwenden,
der kein allgemeines Prinzip zugrunde liegt.
Das führt in einer Spirale zu immer mehr Folgeaufwand, sobald die Konstruktion komplexer
wird.
-
Muss man später gezwungenermaßen doch auf eine modulare Konstruktion umstellen, so
ist der gesamte vorher investierte Aufwand verloren:
Elemente eines Heteroxyls lassen sich nicht auf sanftem Wege in etwas Modulares umwandeln,
denn sie sind per se zu nichts kompatibel.
Bestenfalls kann man das Heteroxyl insgesamt als einen zu aufwendig geratenen Prototyp
betrachten.
Gerade der letztgenannte Umstand führt auch geradewegs in eine emotionale Falle: Bezüglich
jeder neuen Anforderung muss man abwägen,
entweder sofort alles umzustellen oder aber "nur noch die eine letzte Änderung" irgendwie
unterzubringen. So betrachtet wird natürlich der
Aufwand für jede weitere Änderung noch lange deutlich unter demjenigen liegen, der
für die gesamte Umstellung anzusetzen wäre – schon
allein deswegen, weil bei einem länger angewachsenen Heteroxyl kaum jemand noch genau
sagen kann, was eine Ersatzkonstruktion eigentlich alles
leisten müsste.
Umgang damit in der Praxis
Was kann man als Entwickler tun, um die geschilderten Probleme möglichst zu verhindern
oder – im Fall eines schon vorhandenen Heteroxyls –
zumindest nicht weiter zu verschlimmern? Unsere Vorschläge dazu:
- Ganz allgemein ein Bewusstsein dafür entwickeln, auf welche Art man gerade konstruiert:
Arbeitet man an einem Prototyp, an einer modularen
Konstruktion, an einem Monolithen oder bereits an einem Heteroxyl?
- Hat man sich einmal für eine modulare Konstruktion entschieden, dann führt kein Weg
an einer soliden Ausarbeitung der Grundelemente
vorbei, auch wenn man von diesem Zwischenergebnis vorerst einmal "nichts sieht".
- Möglichst frühzeitig darauf hinweisen, wenn Änderungsanforderungen für eine Komponente
eine kritische Grenze überschreiten. Steigende
Unübersichtlichkeit durch größeren Fleiß beherrschen zu wollen, wäre falscher Ehrgeiz.
Besser sollte man sich dafür einsetzen, dass trotz
der Umsetzung einer neuen Anforderung das System insgesamt übersichtlicher wird.
-
Bewusst Verantwortung übernehmen, um einer Fehlentwicklung vorzubeugen. Entwickler
können sich stark darin unterscheiden, welches Ausmaß
an Undurchsichtigkeit in Software sie persönlich noch akzeptabel finden. In einer
komplexen Projektsituation mit mehreren Beteiligten
entsteht aus diesen Unterschieden oft die Tendenz, dass besonders problematische Module
automatisch in die Obhut von Entwicklern mit
diesbezüglich hoher Toleranz gelangen.
Genau so, wie ein Heteroxyl normalerweise schleichend entsteht, kann es auch mit der
Zeit wieder zurückgebaut werden – zumindest in gewissen
Grenzen. Möglich ist das beispielsweise durch die bewusste Isolierung besonders problematischer
Teilkomponenten als eingebettete
Monolithen. So kann man darauf hin arbeiten, das Heteroxyl insgesamt in eine Zusammenstellung
einzelner Monolithen zu überführen und diese
so bald wie möglich einzufrieren. Auf Basis des so gewonnenen Wissens über die bereits
umgesetzten Anforderungen kann dann ein solides
Redesign aufgesetzt werden, sofern sich denn die Bereitschaft dazu auch bei den Verantwortlichen
schon weit genug entwickelt hat.