Hierunter ist die Abgrenzung von Teilen des Systems zu verstehen, die voneinander unabhängigen Lebenszyklen unterliegen. Dieses umfasst insbesondere auch die Unabhängigkeit von allen fremd gesteuerten Schnittstellen im weitesten Sinne.
Unter extern gesteuerten oder
kontrollierten Schnittstellen sind z.B. die Hardware,
Betriebsysteme, Datenbanken, Standards oder konkrete Schnittstellen zu verstehen.
Die völlige Unabhängigkeit ist natürlich wirtschaftlich nicht machbar.
Trotzdem hat es hier bereits erhebliche Fortschritte gegeben.
Betriebssysteme machen andere Software weitgehend unabhängig von der
konkreten Hardware.
Einige Programmiersprachen (z.B. Java) ermöglichen die Unabhängigkeit
vom verwendeten Betriebssystem.
Generische Datenbankzugriffsstandards ermöglichen die Unabhängigkeit
von einer konkreten Datenbank.
Durch Modularisierung und Kapselung aller Programmteile,
die von einem konkreten Standard oder einer konkreten Schnittstelle abhängen,
lassen sich auch hier die Abhängigkeiten reduzieren.
Es geht hier weniger um die völlige Vermeidung aller Abhängigkeiten sondern vielmehr darum,
dass den Entwicklern bewusst ist, dass sie keine Abhängigkeiten fahrlässig
eingehen sollen und dort, wo nicht vermeidbar, zumindest den Grad der
Abhängigkeit minimal halten müssen.
Unter fahrlässig ist in diesem Zusammenhang zu verstehen,
ohne Not bzw. ohne angemessenen Gegenwert
- also z.B. aus mangelndem Problembewusstsein oder Bequemlichkeit.
Angesichts der bestehenden Langzeitrisiken ist auch eine beim
Nutzer
getroffene strategische Entscheidung z.B. für ein Betriebsystem
oder eine Datenbank keinesfalls ein ausreichender Grund, um die
Abhängigkeit einer konkreten Software von dieser Plattform als unkritisch einzustufen
und so eine zukünftige Änderung dieser Entscheidung zu erschweren.
Andererseits ist es auch nicht sinnvoll, in spekulativer Voraussicht
jede unvermeidliche Abhängigkeit hinter Schichten von Indirektionen zu kapseln
und so die Komplexität des Quellkodes in die Höhe zu treiben.
Ziel ist es vielmehr den
Aufwand abschätzbar zu machen, den das
Auflösen einer bestehenden Abhängigkeit auslösen würde, und diesen dann
nicht unnötig zu erhöhen.
Konkret heißt dieses, dass zu einer Software alle externen Abhängigkeiten dokumentiert werden müssen und zu jeder dieser Abhängigkeiten ein operatives Konzept erläutert werden muss, wie im Fall eines Austauschs oder einer externen Veränderung am effizientesten verfahren werden kann.
Ist ein System nicht homogen, so gelten zwischen
den Teilen die selben Grundsätze, wie bezüglich externer Abhängigkeiten.
Baut z.B. in einem System die konkrete Programmierung der Geschäftslogik auf einem
Framework auf, so sind auch hier die Abhängigkeiten und die
Konsequenzen von Veränderungen am Framework aufzuzeigen.
Des weiteren ist in diesem Zusammenhang z.B. auch das Zusammenspiel
von einer Anwendung mit Datenbanken zu sehen.
Welche Auswirkungen haben Änderungen an der Datenbank auf den Programmkode?
Welche Änderungen des Programmkodes erzwingen Änderungen an der Datenbank?
Solche Fragen bekommen besondere Bedeutung, wenn z.B. eine
Datenbank gemeinsam von mehreren Anwendungen genutzt wird.
Ergeben sich bei Änderungen Kaskadeneffekte?
Weiterhin hängen die Risiken und Kosten beim Roll-out neuer Versionen
u.a. davon ab, ob die Änderungen an der Applikation und der Datenbank
zwingend synchron erfolgen müssen, oder ob eine alte Anwendungsversion
mit einer neueren Datenbankversion zusammenarbeiten kann und umgekehrt
- ohne die Integrität der Daten zu zerstören.
Was passiert, wenn ein solcher Zugriff irrtümlich erfolgt?
Auf all diese und ähnliche Fragen müssen
sinnvolle, risikominimierende, technische Antworten
gefunden und umgesetzt werden.
Wo das nicht wirtschaftlich möglich ist, wird zumindest eine
konkrete Dokumentation erforderlich.
Darüber hinaus kann die Qualität der Modularisierung (Kopplung,
Kohäsion) mit allgemeinen Werkzeugen zur Quellkodeanalyse
überprüft werden.
Diese können neben der Prüfung von Programmierrichtlinien viele
Aspekte des Quellkodes ermitteln und in Beziehung zueinander setzen.
So kann z.B. die Verwendung von Entwurfsmustern ermittelt werden (eher gut)
oder die Wiederholung gleichartiger Kodestücke, ganz
unbenutzter Kode, zyklische Beziehungen oder Probleme mit
Vererbungsstrukturen oder Abstraktionen (eher schlecht).
Viele negative Aspekte fallen bereits durch die
Visualisierung von Abhängigkeitsstrukturen auf verschiedenen
Abstraktionsebenen auf.
Einige Werkzeuge ermöglichen auch den
Vergleich der Ist-Architektur mit Architekturvorgaben.
Obwohl es auch Faustregeln und klare Alarmsignale gibt, kann die
konkrete Bewertung der potentiellen Berge von Informationen
jedoch nur im Kontext des konkreten Systems erfolgen.
Die folgenden Referenzen stellen kein Qualitätsurteil dar.
Sie sollen nur einen ersten Einstieg in Aspekte der Materie bieten.
Die konkrete Dokumentation zur Strategie, wie die verbliebenen
Abhängigkeiten effizient aufgelöst werden können,
muss zwar vom Anbieter erstellt werden.
Sie lässt sich jedoch in Bezug auf übliche Abhängigkeiten auch für
andere Projekte wiederverwenden.
Als Beispiele zu den diversen
Werkzeugen zur Analyse der Designqualität von Software seien hier
JDepend und
XRadar
erwähnt, die als Ergebnis eine Reihe von
Kennzahlen liefern und Hinweise auf Stellen
im Quellkode geben, die verbesserungswürdig sind.
Es gehört zu den Best Practices, solche Werkzeuge schon
laufend während des Entwicklungsprozesses einzusetzen,
weil sich identifizierte Probleme im Nachhinein nur noch mit
sehr viel höherem Aufwand beheben lassen.
Als Literaturhinweis mit Kapiteln zu Themen wie
Softwarequalität, Modularisierung und
selbstdokumentierendem Quellkode
sei hier nur ein Klassiker erwähnt: