Zukunftssichere Architektur - Ralf Westphal - E-Book

Zukunftssichere Architektur E-Book

Ralf Westphal

0,0

Beschreibung

Glücklich der, der auf der grünen Wiese eine neuen Anwendung planen und aufbauen darf. Angefangen von der Architektur bis hin zum Layout der Bedienoberfläche kann man dann den neuesten Standards gehorchen. Nur leider gibt es viele Programme, die wunderbar ihren Dienst verrichten, neuen Anforderungen aber angepasst werden müssen. Eine Neuentwicklung will der Kunde nicht bezahlen, also muss man aus dem, was vorliegt, das beste machen. Architekturspezialist Ralf Westphal zeigt Ihnen in diesem Buch, wie Sie vorgehen, wenn Sie so eine Anwendung weiterentwickeln müssen. Wartbarkeit ist das zentrale Thema. Und die erreicht man durch Auftrennung von Monolithen zu komponentenorientierten Anwendungen. Aber wie gehen Sie dabei vor? In Beispielen führt Sie Ralf Westphal Schritt für Schritt durch einen Prozess, an dessen Ende eine Anwendung steht, die sich aus vielen Komponenten zusammensetzt. Jede der Komponenten kann nun ausgetauscht werden, ohne das Gesamtsystem in Mitleidenschaft zu ziehen. Einleitend erklärt der Autor auch noch in zwei Grundlagenartikeln, warum Regeln bei der Implementierung nur Vorteile brauchen und warum die Komponentenorientierung so viele Vorteile mit sich bringt.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern
Kindle™-E-Readern
(für ausgewählte Pakete)

Seitenzahl: 143

Veröffentlichungsjahr: 2012

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



EDITORIAL

Im Wandel liegt die Kraft

Fasst man die zentrale Botschaft der Softwarearchitekten gleich welcher Schule zusammen, könnte sie folgendermaßen lauten:

Monolithische Anwendungen sind tot. Lang lebe die komponentenorientierte Architektur.

So einfach sich diese Botschaft auch anhört, steckt doch in ihr die Erfahrung mit alten und neuen Systemen. Erst dank der Verteilung von Funktionalität auf verschiedene voneinander getrennte Komponenten ist es möglich, auf Forderungen der Kunden und der Entwickler einzugehen.

Erweiterbarkeit: Software lebt. Sie muss sich den sich verändernden Anforderungen anpassen können. rst komponentenorientierte Systeme ermöglichen das auf einfache Weise.

Testbarkeit: Die Qualität einzelner Teile soll durch automatische Tests gesichert werden, auch oder gerade wenn an anderer Stelle umgebaut wird.

Refaktorisierbarkeit: Wer erweitert oder umbaut, der muss Teile der Software verändern. Je feingranula-rer dann die Struktur ist, umso weniger muss verändert werden, was nicht nur Zeit und Geld spart, sondern auch die Qualität nicht verringert:

Dieses DevBook soll Ihnen zeigen, wie Sie Architekturen aufstellen, die auch morgen noch Bestand haben, weil sie sich gegen Veränderungen nicht sperren. Zuerst einmal ist es wichtig, strikte Regeln einzuführen, die später dafür sorgen, dass leicht umgebaut werden kann. Dazu zählen Schnittstellen: Wer Schnittstellen sauber aufstellt, kann einzelne Komponenten ersetzen, ohne dass das System in Mitleidenschaft gezogen wird. Solche Schnittstellen sollten durch automatische Tests gesichert werden. Wer die Schnittstellen durch solche Tests komplett abdeckt, kann sich sicher sein, dass bei einer Veränderung alles noch geht.

Diese Vorbemerkungen legen den Grundstock für das zentrale Thema des Buchs: Umbau einer vorhandenen monolithischen Anwendung. Wie gehen Sie dabei vor? Wo fangen Sie an? Schließlich haben Sie es mit einem Wust an Klassen und Methoden zu tun, die Sie eigentlich alle verstehen müssten.

Aber Ralf Westphal nimmt Sie an die Hand und zeigt Ihnen schrittweise, wie Sie aus der Chaos-Struktur eine sauber strukturierte Anwendung bauen. Abhängigkeiten spielen dabei eine große Rolle. Erst wenn Sie verstanden haben, wer von wem etwas braucht, können Sie den Fitz aufdröseln.

Zum Schluss kommt eine Anwendung heraus, die nicht nur durch ihren Aufbau sehr schnell verstehbar ist. Sie ist auch gleich für künftige Anforderungen oder Änderungen bestens gerüstet.

Beim Zerschneiden helfen - wie oben schon erwähnt - immer wieder Unit-Tests, die Schnittstellen absichern. Diese aber in einer monolithischen Anwendung einzuführen, scheint auf den ersten Blick aussichtslos. Aber auch hier weiß Ralf Westphal Rat und zeigt Ihnen, wie Sie dabei vorgehen.

Viel Spaß beim Lesen und Studieren

Tilman Börner Chefredakteur dotnetpro

Inhalt

Methodik des Softwarebaus: Mehr Regeln wagenWie ein Hausbau braucht auch die Entwicklung von Software Konventionen, um Qualität erreichen zu können.

Semantische Verträge: Doppelt genäht hält besserWer seine Software als Komponenten entwickelt, hat beim Outsourcing die Nase vorn.

Eine Architektur für Legacy-Code 1: Alter Code neu gebautSie sollen eine Software auf das .NET Framework 3.5 migrieren. Dabei soll das Projekt auch architektonisch fit für die Zukunft werden.

Eine Architektur für Legacy-Code 2: Vom IST zum SOLLLegacy-Code muss nicht vom Mainframe stammen. Auch .NET-1.0-Code gilt bereits als "Vermächtnis" von früher. Gehen Sie bei einer Migration systematisch vor!

Eine Architektur für Legacy-Code 3: Landkarten zeichnenMit den entsprechenden Werkzeugen ist es kein Problem, sich unbekanntem Code zu nähern.

Eine Architektur für Legacy-Code 4: Geschafft!Im letzten Teil der Serie formen Sie mithilfe dieser Erkenntnisse ein neues Innenleben für die Software. Dabei machen Sie diese gleich fit für künftige Anpassungen.

Bestehende monolithische Anwendungen für Unit-Tests aufbereiten: Den Sumpf trockenlegenWer Software schreibt, sollte sie sofort auch selbst testen. Aber nicht irgendwie, sondern automatisiert mit Unit-Tests.

codekicker: Fragen und Antworten zur ArchitekturDie wichtigsten Fragen und Antworten zur Softwarearchitektur aus der Wissensbörse codekicker.de.

Eine Monolith-Anwendung für Unit-Tests aufbereiten: Ein Sumpf wird grünEine bestehende monolithische Anwendung mit Unit-Tests nachzurüsten ist möglich. Separate Komponenten und Kontrakte - und schon sind Unit-Tests machbar.

Imprint Zukunftssichere Architektur Ralf Westphal published by: epubli GmbH, Berlin, www.epubli.de Copyright: © NMG

Methodik des Softwarebaus

Mehr Regeln wagen

Wie beim Hausbau braucht auch die Entwicklung von Software Konventionen, um Qualität erreichen zu können. Leider gibt es derzeit davon zu wenig. Mehr Konventionen würden den Entwickler besser leiten, ihm Arbeit und Entscheidungen abnehmen sowie mehr Zeit verschaffen, sich um das eigentliche Problemfeld der Software zu kümmern.

Auf einen Blick

Ralf Westphal ist freier Softwaretechnologievermittler im Bereich .NET-Softwarearchitektur. Er arbeitet als Fachautor, Coach/Berater und Referent auf Entwicklerevents. Sie erreichen ihn über www.ralfw.de.Inhalt:

Beim Entwickeln von Software gibt es zu wenig allgemeingültige Regeln.

Das kostet Zeit und Geld.

Objektorientierung allein reicht nicht aus.

Die Schachtelung von Komponenten würde weiterhelfen.

dotnetpro.code: 

A0806Kolumne

Stellen Sie sich vor, zwei einander unbekannte Softwareentwickler kommen über ihre Projekte ins Gespräch. Was würden sie wohl für Gemeinsamkeiten in der Realisierung ihrer Applikationen feststellen? Beide könnten für dieselbe Plattform entwickeln: Windows und .NET Framework; beide könnten an einer Anwendung derselben Art arbeiten, zum Beispiel eine Desktop- oder Webanwendung; beide könnten Daten in einer relationalen Datenbank speichern.

Und weiter? Sicherlich unterscheiden sich die Problemdomänen, an denen die Entwickler arbeiten. Der eine könnte eine CRM-Software und der andere Immobilienverwaltung schreiben. Sind also nicht mehr Gemeinsamkeiten bei zwei Softwareanwendungen zu erwarten?

Ein paar mögen noch unterhalb der Bewusstseinsschwelle liegen. Sie sind so natürlich, dass die beiden Softwareentwickler sie nicht für erwähnenswert halten. Zum Beispiel programmieren sie beide objektorientiert, zeichnen UML-Diagramme und halten die Normalisierung einer Datenbank für wichtig. Und natürlich haben ihre Anwendungen dieselbe Grundstruktur: Sie bestehen aus einer Benutzeroberfläche, greifen auf Infrastruktur zu und implementieren eine problemdomänenspezifische Logik.

Auf der Oberfläche der Anwendungen würde ein Laie sicherlich grundsätzlich dieselben Steuerelemente finden: Eingabefelder, Menüs, Schaltflächen, Tabellen. Aber darunter? Ist jenseits von Objektorientierung und einer groben Dreigliederung des Codes keine strukturelle Gemeinsamkeit mehr zu erwarten? Vermutlich nicht. Die beiden mögen vielleicht hier und da noch dieselben Entwurfsmuster einsetzen -doch darüber hinaus wird es kaum mehr Gemeinsamkeiten geben.

Jenseits der Werkzeuge und der durch sie vertretenen Konzepte herrscht wenig Konsens in der Softwareentwicklung. Compiler schaffen Gemeinsamkeit bei der Sprache mit ihrem fundamentalen Programmierparadigma. IDEs schaffen Gemeinsamkeit beim Aufbau von Benutzeroberflächen und der Quellcodegrundstruktur. Datenbanken schaffen Gemeinsamkeit bei der Datenorganisation.

Wo Werkzeuge oder Konzepte unbekannt oder nicht weit verbreitet sind, herrscht deshalb im Umkehrschluss keine Gemeinsamkeit; weder in der Vorgehensweise noch in Bezug auf die Produktion oder in Architekturfragen. Die Agilitätsbewegung bemüht sich zwar; Team Foundation Server & Co bemühen sich auch; aber es ist unwahrscheinlich, dass die beiden Entwickler in ihrem Gespräch hier schon viele Gemeinsamkeiten entdecken würden. Und noch unwahrscheinlicher ist es in Bezug auf den grundsätzlichen Aufbau ihrer Anwendungen, also ihre Architektur.

Diese Abwesenheit von Gemeinsamkeiten halte ich für überraschend und kontraproduktiv. Nach 50 Jahren Softwareentwicklungspraxis ist die Zahl der Gemeinsamkeiten zwischen zwei Anwendungen immer noch an einer Hand abzählbar. Das gibt es in keiner anderen Branche. Der Ruf nach Standards ist allerorten zu hören, von den Programmiersprachen über die Kommunikation bis zu Office-Dokumentenformaten; was den inneren Aufbau einer Anwendung angeht, verhallt er ungehört.

Das Resultat: geringe Produktivität. Denn wo kein Konsens herrscht, ist immer erst ein Weg zu bahnen. Das kostet Ressourcen.

Kreativer und produktiver mit Regeln

Mehr Konsens und mehr Systematik tun Not. Softwareentwicklung sollte in mehr Aspekten klaren Regeln und typischen Lösungen folgen, die in mindestens 80 Prozent der Fälle zu ausreichenden Implementierungen führen. Die Normalisierungsregeln für relationale Datenbanken sind dafür vielleicht das beste Beispiel: Sie machen klare Vorgaben, sind leicht umzusetzen, führen zu verständlichen Strukturen und sorgen für Wartbarkeit. In den meisten Fällen sind die sich daraus ergebenden Datenbanken auch effektiv genug. Falls nicht, ist es auch kein Verrat, eine Regel auch mal zu brechen. Den grundsätzlichen Konsens beeinträchtigt das nicht. Er hilft, den Kopf für das Wesentliche, die Problemdomäne, freizuhalten.

Ähnliches gilt auch für die Objektorientierung. Sie ist Konsens, was das allgemeine Programmierparadigma angeht. Dass zwei Entwickler für ein Problem unabhängig voneinander eine objektorientierte Sprache wählen, ist sehr wahrscheinlich. So wird es einfach, produktive Teams zusammenzustellen.

Entwurfsmuster haben das Ziel, Gleiches auf einer höheren Abstraktionsstufe zu wiederholen. Sie definieren ein Vokabular für wiederkehrende Probleme mit probaten Lösungen. MVC und Schichten sind vielleicht die bekanntesten Beispiele. Beide sind übersichtlich und leicht verständlich, beide haben ein klares Anwendungsgebiet. Beim Vorgehensmodell könnte Scrum [1] das Zeug dazu haben, ein konsensfähiges Minimalmuster zu werden.

Konventionen und Regeln bedeuten allerdings nicht sklavisches Befolgen. Sie sollen zunächst nur den Blick leiten und Ordnung in das Chaos bringen. Die schnelle 80-Prozent-Lösung ist ihr Zweck. Sie können selbstverständlich gebrochen werden. Denormalisierung ist nicht nur erlaubt, sondern manchmal einfach geboten. Wer allerdings eine Regel bricht, muss sich erklären. Und das ist gut so. Das schafft Bewusstsein und Verantwortungsgefühl für das, was man tut.

Mehr Regeln machen das Leben leichter, weil sie uns Entscheidungen abnehmen. Sie schaffen sogar Spielräume. Fragen Sie einen Künstler: Der wird Ihnen sagen, dass Kreativität von Beschränkung profitiert, ja, sie geradezu braucht.

Regeln sind auch konform mit der Philosophie der Lean Production und der Agilitätsbewegung, Entscheidungen so spät wie möglich zu treffen. Denn wer nach einer Regel handelt, der muss eigentlich noch keine "richtige" Entscheidung treffen. Er vertagt sie vielmehr, bis es ein Problem mit der Regel gibt. Da das aber qua definitionem selten der Fall ist - sonst wäre eine Regel ja keine Regel, allemal keine gute -, spart er in den meisten Fällen Zeit und Nerven.

Regeln für den Anwendungsbau

Zurück zu den beiden Softwareentwicklern im Gespräch. Mit welcher Konvention würde es dem einen leichter fallen, im Team des anderen mitzuarbeiten? Mehr Konsens in Bezug auf den grundlegenden Aufbau von Software wäre da sicherlich eine große Hilfe.

Eine "Konsensklammer" gibt es schon (Abbildung 1): Plattform und fundamentales Programmierparadigma. Beide Entwickler sind sich auch einig über die Art der Applikation und die Codekategorisierung durch Schichten. Benutzerschnittstelle, Domänenlogik oder Infrastrukturzugriff sind so allgemein, dass diese grobe Einteilung von Code für jede Applikation gelten kann.

[Abb. 1] Konsens herrscht im Fundamentalen und sehr Allgemeinen. Dazwischen liegt allerdings eine weitgehend konventionsfreie Zone.

Konsens im Fundamentalen, Konsens im Allgemeinen. Aber dazwischen klafft eine Lücke, die ressourcenfressende Entscheidungen fordert, weil Konventionen fehlen. Sie zu schließen, würde vielen Entwicklern helfen, sich wieder mehr auf das Wesentliche konzentrieren zu können und produktiver zu arbeiten.

Es geht um einen vergleichsweise kleinen Schritt über die Objektorientierung hinaus. Um etwas, das auf der Objektorientierung aufbaut, deren Werte also nicht negiert; was in Theorie und Praxis verständlich ist. Die Praxis ist sogar sehr wichtig - in Form von Konventionen für die Codierung, weil ansonsten der mühevolle Transfer theoretischer Überlegungen in die Coderealität wieder die Produktivität senkt.

Regeln, welche die festgestellte Lücke verkleinern, sollen einerseits anleiten-, also Unsicherheit nehmen -, andererseits Eigenverantwortung betonen. Konzepte sollten dabei von Werkzeugen unterstützt werden, wo es geht, andererseits aber natürlich weitgehend herstellerneutral sein.

Als Analogie mag der Hausbau dienen. Da gibt es nicht nur grundlegende Konventionen, was die Baumaterialien angeht, und allgemeinen Konsens über die Einteilung eines Hauses in Fundament, Wände und Dach. Die Gemeinsamkeiten zwischen Häusern - auch ganz unterschiedlicher Art - gehen viel weiter. Jedes Haus hat Wasseranschluss und führt Rohre in verschiedene Räume; jedes Haus hat Anschluss ans Elektrizitätsnetz und führt elektrische Leitungen in alle Räume; jedes Haus hat eine Heizungsanlage und führt Heizungsrohre in alle Räume. Ab einer bestimmten Höhe hat jedes Haus Aufzüge, die alle Stockwerke bedienen und dazu ihre Schächte und den Antrieb.

So viele Gemeinsamkeiten, so viele Konventionen - und doch so viel Freiheit. Denn was Sie in den einzelnen Räumen tun, ist Ihnen freigestellt; welche Geräte Sie an die elektrischen Leitungen anschließen, entscheiden Sie. Die Gemeinsamkeiten im Hausbau betreffen eine Infrastruktur, die dazu dient, sich in den Räumen zu entfalten. Sie sollen sich keine Gedanken mehr darüber machen müssen, wie Sie es hell, warm, sauber und bequem haben könnten.

Die Konventionen sorgen dafür, dass ein Haus Bedürfnisse verschiedener Kategorien erfüllen kann. Sie schaffen sozusagen schon die Bedingungen für die Möglichkeit von Dienstleistungen, die zum Beispiel mit Wasser oder Elektrizität zusammenhängen. Welche Dienstleistungen das dann sind, ist egal. Strom und Wasser kommen über Standardanschlüsse ins Haus. Aus den Leistungen, die diese Standards unterstützen, können Sie dann frei wählen.

Genau darum geht es beim Plädoyer für mehr Konventionen bei der Softwareentwicklung: Sie sollen es leichter haben, "Dienstleistungen" in Ihrem "Softwarehaus" zu installieren und zu verbinden. Oder sogar noch grundlegender: Sie sollen überhaupt erst einmal in Dienstleistungen denken - Services statt Verkabelung. Welche Services jedoch, ist egal. Wählen Sie nach Belieben und machen Sie sich keine Sorgen über die Verbindungen. Für die Verkabelung und die Anschlussfähigkeit sorgen die Prinzipien und Technologien des erweiterten Konsens.

Insofern geht es mir nicht um ein Application Framework mit Konventionen für Persistenz, Sicherheit, Benutzerschnittstelle und so weiter. Das wären schon konkrete Dienstleistungen. So verständlich es ist, Arbeit sparen zu wollen, indem Sie sich auf solche Vorgaben einlassen - der Unterschied zwischen Konvention und Korsett ist fließend. Und je höher das Abstraktionsniveau einer Konvention, desto eher stören Sie sich an ihren Beschränkungen. Kompensieren 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 { }