Anbieter zum Thema
Abhängigkeiten – die Wurzel allen Übels?
Eine besonders wichtige Rolle im dynamikrobusten Softwaredesign spielen die Abhängigkeiten. Um mit der hohen Komplexität besser umgehen zu können, werden Softwaresysteme nach dem Prinzip Teile und Herrsche modularisiert, d.h. in kleinere Bausteine zerlegt.
Dabei entsteht in der Regel eine mehrstufige Hierarchie aus Softwarebausteinen auf unterschiedlichem Abstraktionsniveau. Damit diese wieder miteinander kollaborieren können um die von den Stakeholdern geforderten Anforderungen zu erfüllen, existieren zwischen diesen Bausteinen sogenannte Abhängigkeiten.
Unter einer Abhängigkeit versteht man, dass ein Softwarebaustein (etwa eine Klasse) einen anderen Softwarebaustein benötigt, um seine Aufgabe erfüllen zu können. Anders ausgedrückt: der abhängige Baustein ist in seiner Spezifikation und/oder Implementation ohne den unabhängigen Baustein unvollständig. In der Unified Modeling Language (UML) werden Abhängigkeiten zwischen Klassen ganz allgemein durch die dependency relationship (gestrichelter Pfeil) dargestellt (siehe Bild 1 in der Bildergalerie).
Im Sourcecode werden Abhängigkeiten dadurch erzeugt, dass man an irgendeiner Stelle im abhängigen Softwarebaustein den unabhängigen Softwarebaustein verwendet, erzeugt, oder er ist sogar struktureller Bestandteil (beispielsweise ein Attribut der Klasse) des abhängigen Bausteins, was einer sog. Assoziation entspricht. Das lässt sich auch in der UML-Notation unterscheiden (siehe Bild 2 in der Bildergalerie).
Eine weitere, sogar besonders strenge Abhängigkeit, stellt in der Objekt-orientierten Softwareentwicklung die Generalisierung dar (siehe Bild 3 in der Bildergalerie); eine taxonomische Beziehung, die umgangssprachlich auch häufig als Vererbung bezeichnet wird.
In einem modularen Softwaredesign werden Abhängigkeiten schlichtweg benötigt. Die Schmerzen beginnen dann, wenn zu viele und ungünstige Abhängigkeiten existieren. Zu viele und falsche Abhängigkeiten können die Evolvierbarkeit einer Software drastisch verringern, womit auch ihre Robustheit gegenüber dem dynamischen Umfeld zurückgeht. Auch die Testbarkeit eines solchen Systems nimmt rapide ab.
Infolgedessen steigen die Aufwände in der Entwicklung an. Aufwandsschätzungen werden immer pessimistischer, Terminzusagen können nicht mehr eingehalten werden, und die Fehlerrate steigt. „Never touch a running system!“ ist ein Statement, das man in einem solchen Projekt häufig hört.
Das hat auch ökonomische Konsequenzen, denn die betriebliche Wertschöpfung in der Entwicklungsorganisation geht zurück. Im schlimmsten Fall endet das Ganze in einem sehr teuren Wartungsalbtraum, oder sogar in einer Havarie, d.h. es führt zu einem Projektabbruch.
Die gute Nachricht: Man ist einer ungünstigen Abhängigkeitssituation in einer Software nicht hilflos ausgeliefert, denn Abhängigkeiten können gestaltet werden. Damit eine Software evolvierbar bleibt, sollten Entwickler einige Prinzipien beachten und Praktiken beherrschen, die ich im Folgenden nur kurz vorstellen möchte, die aber im Konferenzvortrag ausführlicher präsentiert werden.
(ID:44130029)