können Sie das dann nur durch eine Einengung Ihrer Bedürfnisse, zum Beispiel im Hinblick auf die Art der Anwendung oder des Bedienmodells.
Wenn Sie also flexibel bleiben und dennoch Produktivitätsgewinn aus mehr Regeln ziehen wollen, dann müssen Sie die Konventionenlücke aus Abbildung 1 schrittweise von unten her schließen.
Objektorientierung skaliert nicht
Objektorientierung im Verein mit Entwurfsmustern und UML ist in weiten Bereichen der Softwareentwicklung der kleinste gemeinsame Nenner. Konzepte und Werkzeuge sind in den Lehrplänen der Ausbildungsinstitute angekommen. Das ist gut so. Allerdings ist es nicht genug. Auf die Objektorientierung will natürlich niemand mehr verzichten. Da machen selbst dynamische Sprachen oder funktionale Programmierung keinen Unterschied. Auch die haben sich die Objektorientierung zu eigen gemacht. Objektorientierung leidet jedoch fundamental unter einem Defizit: Sie bietet kein Mittel zur Beschreibung von Software auf mehreren Abstraktionsebenen. Objekte und Klassen sind ihre einzigen Strukturelemente. Das ist so, als hätten Sie nur Legosteine, um ein Haus zu bauen, und nur Bilder von Lego-steinen, um das Haus vorher zu planen.
Kompliziertes und allemal Komplexes ist aber nur zu meistern, wenn dazu nicht nur Bausteine von nur einer Granularität zur Verfügung stehen. In Abbildung 2 [2] sehen Sie ein - ja was? Ein Auto. Aber das erkennen Sie vor allem an den Reifen. Ohne die Reifen würden Sie lange rätseln, was all die kleinen Bausteinchen zusammen wohl ergeben würden. Da helfen auch die erkennbaren Beziehungen zwischen ihnen nichts.
[Abb. 2] Das Ganze verliert sich im Wald der Details.
Die Explosionszeichnung enthält nur eine Beschreibungsebene - und zwar die niedrigst mögliche, die der unteilbaren Bauteile. Auf demselben Niveau bewegt sich eine Softwarebeschreibung mittels Klassendiagramm. Auch dort sind alle Strukturelemente auf demselben Niveau -nur sind deren Beziehungen noch komplizierter. Da gibt es nicht nur Assoziationen und Aggregationen wie in Abbildung 2, sondern auch noch Spezialisierungen. Außerdem sind die Beziehungen womöglich noch mit Rollen und Aritäten annotiert. Nicht zu vernachlässigen ist auch, dass alle Klassen/Objekte in Softwarediagrammen grundsätzlich gleich aussehen; Sie können also nicht einmal aus ihrer Form Rückschlüsse auf den Zweck ziehen, wie dies Abbildung 2 noch erlaubt.
Etwas Komplexeres als ein Auto beschreiben wir also nur mit demselben, überkommenen Mittel. Wie wenig hilfreich das ist, zeigt Abbildung 3 [3]. Selbst der Hinweis, dass es sich dabei um eine Persistenzbibliothek handelt, macht die Sache nicht viel klarer.
[Abb. 3] Die Software verliert sich im Wald der Klassen.
Wenn ein Ganzes unbekannt ist, dann nützt es nichts, seine Details zu zeigen. Denn das Ganze ist mehr als die Summe seiner Teile. Erst im Lichte des Zwecks des Ganzen ergeben Teile nämlich Sinn. Sehen Sie nur die Teile mit ihrem Teilzweck, dann ist es mühsam bis unmöglich, aus den vielen Teilen den Sinn hinter ihrer Existenz abzuleiten.
Kompliziertes und Komplexes auf mehreren Ebenen zu beschreiben, von denen die Bauteilebene nur die unterste ist, hat sich deshalb schon lange eingebürgert. Vom Allgemeinen zum Speziellen, vom Ganzen zum Teil, vom Großen zum Kleinen, top-down: So funktioniert verständliche, übersichtliche Darstellung. Dabei ist die wichtigste Beziehung zunächst einmal die Enthalten-Beziehung. Strukturelemente auf Ebene n enthalten die Strukturelemente auf Ebene n+1. Nur so können Details wahrhaft verborgen werden. Solange Sie sie nicht sehen wollen, sind sie in einem Ganzen versteckt. Die natürliche Darstellung für solche Ebenenvielfalt zeigt Abbildung 4; für viele Ebenen und Details ist dies nur leider umständlich, ja sogar verwirrend. Als probate Alternative hat sich deshalb ein Baum wie in Abbildung 5 erwiesen.
[Abb. 4] Darstellung eines Systems und seiner unterschiedlichen Abstraktionsgrade.
[Abb. 5] Die übersichtliche Baumdarstellung eines Systems mit mehreren Abstraktionsebenen.
Durch ihn können Sie horizontal Schnitte legen (Abbildung 6), um ein System auf unterschiedlichen Abstraktionsebenen zu beschreiben. Dazu bedarf es allerdings physischer Schachtelung, sonst ist die Darstellung nicht wahrhaftig.
[Abb. 6] Horizontale Schnitte durch das geschachtelte System aus Abbildung 5.
Die Objektorientierung bietet nun aber eben nicht mehr als das, was Abbildung 3 zeigt. Punkt. Physische Schachtelung gibt es nicht, auch nicht beim .NET Framework. Private Klassen sollen ein Sonderfall bleiben und Namensraumdefinitionen sind nur "syntactic sugar". Dem mögen Sie nun entgegenhalten, dass es doch Kompositionsbeziehungen gebe. Sie kennzeichnen Objekte als enthalten in einem anderen.
In Abbildung 7 enthält ein Kunde- Objekt Adresse-Objekte, es besteht also - unter anderem - aus ihnen; Adressen haben ohne Kunde keine Existenzgrundlage.
[Abb. 7] In Ermangelung echter Schachtelungsmöglichkeit müssen Teil-Objekte über Kompositi onsbeziehungen zu einem Ganzes-Objekt zusam mengesetzt werden.
Diese Denkweise ist jedoch recht künstlich und nur dem Mangel an weiteren Struktur- und physischen Abstraktionsebenen geschuldet. So laufen Modell und Coderealität schnell auseinander. Denn im Code lässt sich diese Beziehung ja nicht physisch ausdrücken. Einer Definition wie der folgenden sieht man die gewünschte Schachtelung nicht mehr an:
class Kunde
{
List adressen;
}
class Adresse { }
In der Objektorientierung fehlt also die Möglichkeit, zwei solche Klassen wirklich in einen "Sack" stecken zu können, der sie tatsächlich "enthält" (Abbildung 8). Das ist misslich, denn solange das nicht geht, gibt es nur Besitz-Beziehungen - also eine Assoziation wie "Ein Kunde hat Adressen" -und keine echten Kompositionen oder Aggregate wie "Ein Kunde besteht aus Kopfdaten und Adressen". Wo aber keine Schachtelung möglich ist, da wird das Denken auf unterschiedlichen Abstraktionsebenen erschwert.
[Abb. 8] Echte Abstraktion von den Details einer Entität durch Schachtelung.
Das bedeutet, je umfangreicher oder komplizierter ein System wird, desto schwieriger wird die Modellierung mit den auf ein Abstraktionsniveau festgenagelten Strukturelementen. Mit einem Wort: Ska-lierbarkeit ist keine Sache der Objektorientierung.
Geschachtelte Komponenten
Software muss auf beliebig vielenAbstraktionsebenen darstellbar sein. Die Modellierungselemente müssen daher schachtelbar sein. Modelle laufen immer Gefahr, von der Realität überholt zu werden. Das führt zu Pflegeaufwand beim Modell, weil es immer wieder der Implementierung nachgeführt werden muss. Wenn allerdings die Modellierungselemente gleichzeitig auch Implementierungsartefakte sind, ist dieser Gefahr zu begegnen. Denn dann kann das Modell aus der Coderealität bei Bedarf generiert werden. Die Klassendiagramme in Visual Studio sind dafür ein Beweis.
Um die Anforderung nach Schachtelbar-keit und Modell-Codeartefakt-Dualität zu erfüllen, schlage ich vor, die Konventionenlücke von unten mit Komponentenorientierung zu füllen. Komponente definiert sich für diesen Zweck minimal als:
Binäre Codeeinheit- denken Sie "Assembly" -
mit einem separaten Kontrakt - denken Sie wieder