18.02.2014 Aufrufe

Softwaretechnik

Softwaretechnik

Softwaretechnik

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

<strong>Softwaretechnik</strong><br />

Zusammenfassung der Methodik der Vorlesung im Wintersemester 2010/2011<br />

INHALT<br />

1 Objektorientierte Analyse ............................................................................................................... 3<br />

1.1 Use Case – Modell ................................................................................................................... 3<br />

1.1.1 Aktoren bestimmen ......................................................................................................... 3<br />

1.1.2 Anwendungsfälle bestimmen .......................................................................................... 3<br />

1.1.3 Diagramm erstellen ......................................................................................................... 3<br />

1.1.4 Beschreibungen anfertigen ............................................................................................. 3<br />

1.2 Statisches Modell .................................................................................................................... 4<br />

1.2.1 Klassen identifizieren ....................................................................................................... 4<br />

1.2.2 Assoziationen bestimmen ............................................................................................... 4<br />

1.2.3 Attribute identifizieren .................................................................................................... 5<br />

1.2.4 Vererbung einführen ....................................................................................................... 5<br />

1.2.5 Modell überarbeiten ....................................................................................................... 5<br />

1.3 Dynamisches Modell ............................................................................................................... 5<br />

1.3.1 Interaktionsdiagramme entwickeln ................................................................................ 5<br />

1.3.2 Zustands- und Aktivitätsdiagramme entwickeln ............................................................. 6<br />

2 Objektorientierter Entwurf ............................................................................................................. 7<br />

2.1 Objektentwurf ......................................................................................................................... 7<br />

2.1.1 Operationen hinzufügen ................................................................................................. 7<br />

2.1.2 Assoziationen ausrichten ................................................................................................. 8<br />

2.1.3 Zugriffsrechte bestimmen ............................................................................................... 8<br />

2.1.4 Mehrfachvererbung auflösen .......................................................................................... 8<br />

2.1.5 Wiederverwendung von Klassen ..................................................................................... 8<br />

2.2 Realisierung von Zustandsdiagrammen .................................................................................. 8<br />

2.2.1 Prozedurgesteuerte Realisierung .................................................................................... 9<br />

2.2.2 Realisierung durch Fallunterscheidung ........................................................................... 9<br />

2.2.3 Realisierung durch Zustandsobjekte ............................................................................... 9<br />

2.2.4 Realisierung durch eine Zustandsmaschine .................................................................. 10<br />

2.3 Systementwurf ...................................................................................................................... 10<br />

2.3.1 Grundlagen .................................................................................................................... 10


2.3.2 Fassadenklassen ............................................................................................................ 10<br />

2.3.3 Schichtenarchitekturen ................................................................................................. 11<br />

2.3.4 Drei-Schichten-Architektur für betriebliche Informationssysteme ............................... 11<br />

2.3.5 Kontrollobjekte .............................................................................................................. 11<br />

2.3.6 Beobachter .................................................................................................................... 11<br />

Anmerkung:<br />

Der folgende Text versteht sich mit Blick auf die Klausur als Zusammenfassung zur gleichnamigen Vorlesung<br />

und fußt dazu natürlich auf die von Prof. Dr. Hennicker erstellten Inhalte.<br />

Quelle: http://www.pst.ifi.lmu.de/Lehre/wise-10-11/swtechnik<br />

Der Autor übernimmt keinerlei Gewährleistung dafür, dass diese Zusammenfassung inhaltlich vollständig oder<br />

korrekt ist. Die Benutzung erfolgt also zu eigenem Vergnügen – und auf eigene Gefahr. ;)<br />

Daniel Buschek


3<br />

1 OBJEKTORIENTIERTE ANALYSE<br />

Ziel: Die Anforderungen an das Softwaresystem erfassen und präzise und verständlich beschreiben.<br />

1.1 Use Case – Modell<br />

Input: Informelle, knappe Beschreibung, z.B. aus einem Interview.<br />

Ziel: Die (vom Kunden) gewünschte Funktionalität des Systems beschreiben.<br />

1.1.1 Aktoren bestimmen<br />

Zunächst sollen die Aktoren bestimmt werden, die mit dem System interagieren:<br />

• Wer benützt das System?<br />

• Wer holt Informationen vom System?<br />

• Wer liefert dem System Informationen?<br />

1.1.2 Anwendungsfälle bestimmen<br />

Nun können die Anwendungsfälle bestimmt werden; diese beschreiben die Aufgaben, die das<br />

System für einen oder mehrere Aktoren erledigen soll.<br />

Hierbei besteht oft die Schwierigkeit, die richtige Granularität zu finden: Welche Alternativen<br />

gehören noch zum selben Anwendungsfall, was ist schon ein neuer Anwendungsfall?<br />

1.1.3 Diagramm erstellen<br />

Nachdem Aktoren und Anwendungsfälle bestimmt wurden, kann ein entsprechendes<br />

Anwendungsfall-Diagramm (Use Case – Diagramm) erstellt werden. Eventuell kann hier noch eine<br />

kurze Beschreibung der Aktoren und Anwendungsfälle angegeben werden.<br />

1.1.4 Beschreibungen anfertigen<br />

In diesem letzten Schritt werden die Anwendungsfälle (iterativ) mit Beschreibungen versehen. Diese<br />

haben folgendes Format:<br />

• Name des Anwendungsfalls<br />

• Kurzbeschreibung<br />

• Vorbedingung: Was ist Voraussetzung für eine erfolgreiche Ausführung des Anwendungsfalls?<br />

• Nachbedingung: Beschreibung des Zustands nach erfolgreicher Ausführung.<br />

• Primärszenario: Beschreibt den schrittweisen Ablauf im Normalfall.<br />

• Sekundärszenarien: Beschreiben den schrittweisen Ablauf bei Fehlerfällen oder Optionen.


4<br />

1.2 Statisches Modell<br />

Input: Das Use Case – Modell, die ursprüngliche Problembeschreibung, erweitert um Experten- und<br />

Allgemeinwissen.<br />

Ziel: Ein Klassendiagramm, noch ohne Operationen.<br />

1.2.1 Klassen identifizieren<br />

Es sollen die Klassen für das statische Modell gefunden werden. Kandidaten dafür sind Personen<br />

bzw. Rollen, Organisationen, Gegenstände und begriffliche Konzepte (z.B. Bestellung).<br />

Vorgehensweise:<br />

1. Kandidaten notieren:<br />

Hierzu durchsucht man die Use Case – Beschreibungen nach Substantiven.<br />

2. Ungeeignete Klassen streichen:<br />

Es sollen Klassenkandidaten gestrichen werden, die redundant, irrelevant oder vage sind. Ebenso<br />

eignen sich manche der gefundenen Substantive möglicherweise besser als Attribut einer anderen<br />

Klasse oder es handelt sich um eine Tätigkeit.<br />

3. Fehlende relevante Klassen hinzufügen:<br />

Hinweise auf fehlende Klassen ergeben sich aus Problembereichswissen und aus Attributen vom<br />

vorigen Schritt, zu denen es noch keine Klassen gibt.<br />

1.2.2 Assoziationen bestimmen<br />

Nun sollen Assoziationen zwischen den Klassen gefunden werden. Kandidaten dafür sind<br />

physische/logische Verbindungen mit bestimmter Dauer, z.B. konzeptionelle Verbindungen<br />

(„arbeitet für“), Besitz („hat“, „ist Teil von“) sowie häufige Zusammenarbeit von Objekten zur Lösung<br />

einer Aufgabe.<br />

Vorgehensweise:<br />

1. Kandidaten notieren:<br />

Hierzu durchsucht man die Use Case – Beschreibungen nach Verben, Substantiven im Genitiv („die<br />

Karte des Kunden“) oder Possessivpronomen („seine“, „ihre“, …). Achtung: Verben bezeichnen oft<br />

Aktivitäten statt Beziehungen.<br />

2. Ungeeignete Assoziationen streichen:<br />

Vor allem auf redundante (abgeleitete) Assoziationen sollte verzichtet werden.<br />

3. Fehlende relevante Assoziationen hinzufügen:<br />

Analog zur Vorgehensweise beim Bestimmen der Klassen.<br />

4. Multiplizitäten und ggf. explizite Rollennamen hinzufügen:<br />

Im Zweifelsfall kann man die Multiplizitäten aber auch noch weglassen und erst später bestimmen.


5<br />

1.2.3 Attribute identifizieren<br />

Bei der Suche nach Attributen gelten folgende Richtlinien:<br />

• Es sollen nur für die Anwendung relevante Attribute eingeführt werden.<br />

• Attribute sollen keine Objekttypen haben, dafür werden Assoziationen verwendet.<br />

• Die genauen Attributtypen können noch weggelassen werden.<br />

1.2.4 Vererbung einführen<br />

In der Analyse geht es hierbei vor allem um Generalisierung: Gemeinsame Merkmale der<br />

vorhandenen Klassen (Attribute, Assoziationen) können in einer Oberklasse zusammengefasst<br />

werden. Außerdem sollte hier bestimmt werden, welche Klassen abstrakt sind.<br />

1.2.5 Modell überarbeiten<br />

Im Prinzip besteht dieser Schritt aus dem „Überdenken“ der bisherigen Arbeit. Checkliste:<br />

• Fehlen Klassen oder Assoziationen?<br />

• Sind alle Klassen und Assoziationen notwendig?<br />

• Sind alle Attribute und Assoziationen richtig platziert?<br />

• Gibt es Assoziationen, bei denen ein Qualifizierer sinnvoll wäre?<br />

• Welche Typen haben/bekommen die Attribute?<br />

• Fehlen noch Multiplizitäten?<br />

1.3 Dynamisches Modell<br />

Input: Use Case – Beschreibungen (Szenarien) und statisches Modell.<br />

Ziel: Entwurf von Interaktionsdiagrammen für jeden Anwendungsfall, auf deren Basis dann Zustandsund<br />

Aktivitätsdiagramme abgeleitet werden.<br />

1.3.1 Interaktionsdiagramme entwickeln<br />

Interaktionsdiagramme beschreiben die Zusammenarbeit und den Nachrichtenaustausch zwischen<br />

mehreren Objekten. In UML gibt es Sequenzdiagramme und Kommunikationsdiagramme. Im<br />

Rahmen der Vorlesung bzw. Übung wurden nur Sequenzdiagramme auch wirklich verwendet.<br />

Vorgehensweise:<br />

1. Identifizieren der Nachrichten, die innerhalb eines Anwendungsfalls ausgetauscht werden und<br />

der Objekte, die die Nachrichten senden und empfangen.<br />

2. Konstruktion von Interaktionsdiagrammen für jeden Anwendungsfall bzw. dessen Szenarien.


6<br />

1.3.2 Zustands- und Aktivitätsdiagramme entwickeln<br />

Input: Die im vorigen Schritt erstellten Sequenzdiagramme zu den Anwendungsfällen.<br />

Ziel: Ein Zustandsdiagramm für jede Klasse mit „interessanten Verhalten“ entwickeln (Klassen deren<br />

Objekte einen nicht-trivialen Lebenszyklus haben). Die in den Zustandsdiagrammen auftauchenden<br />

Operationen sollen dann mit Aktivitätsdiagrammen beschrieben werden.<br />

Zustands- und Aktivitätsdiagramme erfassen also das vollständige Verhalten eines jeden Objekts<br />

einer Klasse über viele Szenarien hinweg. Aktivitätsdiagramme können auch weggelassen werden,<br />

wenn es bereits ein einziges Interaktionsdiagramm gibt, das schon das vollständige Ablauf-Verhalten<br />

der Operation zeigt.<br />

Kriterien für „interessantes Verhalten“:<br />

• Ein Objekt reagiert auf gleiche Ereignisse in Abhängigkeit seines Zustands unterschiedlich.<br />

• Mindestens ein Ereignis wird in bestimmten Zuständen ignoriert (bzw. kann dort gar nicht<br />

auftreten).<br />

Typische zustandsabhängige Objekte sind Kontrollobjekte für Anwendungsfälle und<br />

Benutzerschnittstellen, Geräte (z. B. Digitaluhr) sowie Objekte mit beschränktem Fassungsvermögen<br />

(voll, leer).<br />

Klassifizierung von Zuständen:<br />

• stabiler/inaktiver Zustand: Ein Zustand, dem keine Aktivität zugeordnet ist.<br />

• Aktivitätszustand: Ein Zustand, dem eine Aktivität zugeordnet ist und der nur durch ein (evtl.<br />

bedingtes) Completion Event verlassen werden kann.<br />

Vorgehensweise zur Konstruktion eines Zustandsdiagramms:<br />

1. Wahl eines Sequenzdiagramms, das eine typische Interaktion für ein Objekt der betrachteten<br />

Klasse zeigt (normalweise das Sequenzdiagramm für das Primärszenario).<br />

2. Betrachten der Lebenslinie des Objekts.<br />

3. Bilden einer Kette von Zuständen, wobei man der Lebenslinie des Objekts folgt:<br />

• Inaktive Phasen werden durch stabile Zustände modelliert.<br />

• Aktive Phasen werden durch Aktivitätszustände umgesetzt, in denen lokale Operationen<br />

zur Durchführung der Aktivität aufgerufen werden (dies wird später in den<br />

Aktivitätsdiagrammen dargelegt).<br />

• Eintreffende Ereignisse werden durch entsprechend markierte Transitionen von stabilen<br />

Zuständen in Aktivitätszustände modelliert.<br />

• Das Ende von aktiven Phasen wird durch eine Transition mit einem Completion Event<br />

von einem Aktivitätszustand in einen stabilen Zustand umgesetzt.<br />

4. Bilden von Zyklen für Abläufe, die wiederholt werden können.<br />

Damit ist dann ein Sequenzdiagramm verarbeitet, freilich noch ohne die Details zu den Aktivitäten.<br />

Die angegebenen Schritte wiederholt man für alle Sequenzdiagramme, in denen ein Objekt der


7<br />

betrachteten Klasse eine Rolle spielt und erweitert das Zustandsdiagramm entsprechend. Meist führt<br />

diese Erweiterung zu Verzweigungen von einem stabilen Zustand aus, der in mehreren<br />

Sequenzdiagrammen als Ausgangszustand des Objekts auftauchte.<br />

Anschließend folgt die Konstruktion von Aktivitätsdiagrammen für die lokalen Operationen (also die<br />

Operationen in den Aktivitätszuständen des erstellten Zustandsdiagramms).<br />

Außerdem kann das Zustandsdiagramm evtl. noch durch das Hinzufügen von Bedingungen bei den<br />

von Aktivitätszuständen ausgehenden Transitionen verfeinert werden. Dies ist wichtig, damit das<br />

Zustandsdiagramm deterministisch ist!<br />

Zuletzt müssen evtl. auch noch weitere angegebene Sekundärszenarien integriert werden, für die<br />

gar kein Sequenzdiagramm erstellt wurde.<br />

2 OBJEKTORIENTIERTER ENTWURF<br />

Input: Das statische und dynamische Modell der objektorientierten Analyse.<br />

Ziel: Ein Modell der Systemimplementierung; also wie die einzelnen Aufgaben gelöst werden.<br />

2.1 Objektentwurf<br />

Das statische Analysemodell wird nun erweitert und überarbeitet. Dazu verwendet man die<br />

Informationen aus dem dynamischen Modell der Analyse. Die beiden Modelle werden also<br />

zusammengeführt.<br />

2.1.1 Operationen hinzufügen<br />

Das statische Modell soll um Operationen erweitert werden.<br />

Vorgehensweise:<br />

1. Betrachten der Interaktionsdiagramme: Für jede an ein Objekt der Klasse K gesendete Nachricht<br />

wird eine entsprechende Operation bei K eingeführt.<br />

2. Betrachten der Zustands- und Aktivitätsdiagramme: Es wird eine Operation eingeführt für jedes<br />

Call-Event eines Zustandsdiagramms und für jede in einem Aktivitätszustand aufgerufene (lokale)<br />

Operation. Das gilt natürlich auch für Aktionen in den zugehörigen Aktivitätsdiagrammen.<br />

3. Benutzerdefinierte Konstruktoren bei nicht-abstrakten Klassen hinzufügen.<br />

4. Benötigte Zugriffsoperationen für Attribute und Rollen hinzufügen (also Getter- und Setter).<br />

5. Beschreiben der Algorithmen der Operationen (z. B. in Java-Pseudocode).


8<br />

2.1.2 Assoziationen ausrichten<br />

Mit diesem Schritt sollen bidirektionale Assoziationen vermieden werden, was die spätere<br />

Implementierung erleichtert. Dazu wird betrachtet, in welche Richtung die bestehenden<br />

Assoziationen durchlaufen werden (z.B. beim Senden von Nachrichten oder Operationsaufrufen).<br />

Wenn sich dabei herausstellt, dass dies nur in eine Richtung geschieht, wird die Assoziation<br />

entsprechend ausgerichtet.<br />

2.1.3 Zugriffsrechte bestimmen<br />

Nun werden die Zugriffsrechte für Attribute, Rollennamen und Operationen festgelegt. Attribute und<br />

Rollennamen sollten dabei nicht öffentlich zugreifbar sein.<br />

2.1.4 Mehrfachvererbung auflösen<br />

Dieser Schritt ist notwendig, wenn die bei der Implementierung benutzte Sprache keine<br />

Mehrfachvererbung unterstützt (z.B. Java). Die Auflösung wird durch die Einführung einer<br />

Schnittstelle umgesetzt.<br />

Eine der beiden Oberklassen wird durch ein Interface ersetzt, das an ihrer Stelle von der Unterklasse<br />

geerbt (bzw. implementiert) wird. Zudem wird eine neue Klasse erstellt, welche die entfernte<br />

Oberklasse ersetzen soll (vermutlich gleiche Implementierung). Diese neue Klasse implementiert<br />

ebenfalls das eingeführte Interface und wird von der Unterklasse zur Delegation bei Aufrufen der<br />

Operationen aus dem Interface benutzt.<br />

Beispieldiagramme dazu finden sich im Skript in Kapitel 4.1.4 (Folie 11).<br />

2.1.5 Wiederverwendung von Klassen<br />

Oft bestehen bereits erprobte und hochwertige Klassen, die man im Entwurf wiederverwenden<br />

möchte. Braucht man noch mehr Funktionen als die vorhandenen, kann man diese durch<br />

Spezialisierung in einer Subklasse hinzufügen.<br />

Achtung: Vielleicht bietet die geerbte Klasse mehr Operationen an, als man eigentlich benötigt.<br />

Dadurch könnte das Kapselungsprinzip verletzt werden. In einem solchen Fall bietet sich eine<br />

Wiederverwendung durch Delegation an. Hierbei bekommt die neue Klasse ein (privates) Objekt der<br />

wiederverwendeten Klasse, an das sie bei Bedarf Methodenaufrufe weiterleiten kann.<br />

2.2 Realisierung von Zustandsdiagrammen<br />

Input: Das Zustandsdiagramm einer Klasse.<br />

Ziel: Ein Objektentwurf mit Algorithmen zur Realisierung des durch das Zustandsdiagramm<br />

beschriebenen Verhaltens.<br />

Zustandsdiagramme können systematisch realisiert und in den Objektentwurf integriert werden.<br />

Dazu gibt es vier Möglichkeiten, die im Folgenden beschrieben werden.


9<br />

2.2.1 Prozedurgesteuerte Realisierung<br />

Bei diesem Ansatz werden Ereignisse durch erzwungene Benutzereingaben unterschieden. Das setzt<br />

voraus, dass es sich bei den Objekten um Kontrollobjekte zur Dialogsteuerung handelt und sich diese<br />

somit an der Systemgrenze befinden.<br />

Vorgehensweise:<br />

Das gesamte Zustandsdiagramm wird überführt in eine Prozedur mit:<br />

• modalen Dialogen für die (externen) Ereignisse<br />

• bedingten Anweisungen für Verzweigungen<br />

• Wiederholungsanweisungen für Zyklen des Diagramms<br />

Anmerkung: Diese Methode ist heutzutage offensichtlich keine allzu gute Idee mehr; flexible<br />

Benutzerschnittstellen sind so nur schwer zu realisieren.<br />

2.2.2 Realisierung durch Fallunterscheidung<br />

Hier merkt sich das Objekt seinen Zustand in Form eines Attributs. In den Operationen kann dann<br />

anhand dieses Wertes entschieden werden, wie sie sich zu verhalten haben.<br />

Vorgehensweise:<br />

1. Ein Enumerationstyp stellt die endlich vielen (stabilen) Zustände dar.<br />

2. Die Klasse bekommt ein explizites Zustandsattribut dieses Typs.<br />

3. Die zustandsabhängigen Operationen werden durch Fallunterscheidung nach dem aktuellen<br />

Wert des Zustandsattributs realisiert.<br />

Vorteil: Leichte Erweiterbarkeit bezüglich neuer Operationen. Eine neue Operation wird einfach zur<br />

Klasse hinzugefügt und nutzt die Fallunterscheidung nach dem Wert des Zustandsattributs.<br />

Nachteil: Schlechte Erweiterbarkeit bezüglich neuer Zustände. Ein neuer Zustand bedeutet<br />

möglicherweise Veränderungen (nämlich einen neuen Fall) bei den Fallunterscheidungen in allen<br />

bisherigen Operationen.<br />

2.2.3 Realisierung durch Zustandsobjekte<br />

Ein spezielles Zustandsobjekt übernimmt hier die Ausführung der zustandsabhängigen Operationen.<br />

Vorgehensweise:<br />

1. Jedes Objekt der Klasse bekommt ein Zustandsobjekt, das den aktuellen Zustand repräsentiert.<br />

2. Aufrufe von zustandsabhängigen Operationen werden an das Zustandsobjekt delegiert.<br />

3. Das aktuelle Zustandsobjekt führt die gewünschte Aktivität aus und gibt den (neuen) Zustand<br />

zurück, der nun mit dem Basisobjekt verbunden werden soll.


10<br />

Vorteil: Leichte Erweiterbarkeit bezüglich neuer Zustände. Ein neuer Zustand kann einfach als neue<br />

Unterklasse der abstrakten Zustandsklasse umgesetzt werden.<br />

Nachteil: Schlechte Erweiterbarkeit bezüglich neuer Operationen. Eine neue Operation muss<br />

zumindest in die Klasse und den abstrakten Zustand aufgenommen werden; möglicherweise aber<br />

leider auch in alle bisherigen Zustands-Unterklassen.<br />

2.2.4 Realisierung durch eine Zustandsmaschine<br />

Dieser Ansatz realisiert das Zustandsdiagramm, in dem dieses komplett mit verbundenen Objekten<br />

„nachgebaut“ wird.<br />

Idee:<br />

• Alle in einem Zustandsdiagramm vorkommenden Größen (stabile Zustände, Transitionen,<br />

Aktivitäten, Ereignisse) werden durch Objekte dargestellt.<br />

• Ereignisse werden von einer speziellen „Event-Handle“-Operation interpretiert.<br />

• Das gesamte Zustandsdiagramm wird durch eine verzeigerte Objektstruktur repräsentiert.<br />

2.3 Systementwurf<br />

Ziel: Der Objektentwurf soll in die Systemumgebung eingebettet werden. Außerdem wird die<br />

Systemarchitektur festgelegt.<br />

2.3.1 Grundlagen<br />

Die Systemarchitektur beschreibt die Gesamtstruktur des Software-Systems durch Angabe von<br />

Subsystemen und Beziehungen zwischen diesen. Eine grobe Systemarchitektur wird meist schon zu<br />

Beginn der Systementwicklung angegeben. Subsysteme werden durch Pakete oder durch<br />

Komponenten (mit Schnittstellen) dargestellt.<br />

Grundregeln:<br />

• hohe Kohärenz (high cohesion):<br />

Systemteile die (logisch) zusammen gehören sollen in einem Subsystem zusammengefasst werden.<br />

• geringe Kopplung (low coupling):<br />

Zwischen den Subsystemen sollen möglichst wenige Abhängigkeiten bestehen.<br />

→Vorteil: Änderung und Austauschen von einzelnen Teilen wird vereinfacht.<br />

2.3.2 Fassadenklassen<br />

Mit Hilfe von Fasadenklassen kann eine geringe Kopplung erreicht werden. Sie vereinen die Dienste<br />

verschiedener Klassen eines Subsystems durch Delegation der Aufrufe an die zuständigen Objekte.<br />

Ein Beispiel dazu findet sich im Skript in Kapitel 4.3.2 (Folie 50).


11<br />

2.3.3 Schichtenarchitekturen<br />

In einer Schichtenarchitektur stellt jede Schicht Dienste für die darüber liegende(n) Schicht(en)<br />

bereit. Ein bekanntes Beispiel ist das OSI-Modell.<br />

• Bei „geschlossenen“ Architekturen darf eine Schicht nur auf die direkt darunterliegende Schicht<br />

zugreifen, andernfalls spricht man von einer „offenen“ Architektur.<br />

• Als Client/Server-System bezeichnet man eine Verteilung der Schichten auf verschiedene Rechner.<br />

• Eine Schicht kann selbst aus verschiedenen Subsystemen bestehen.<br />

2.3.4 Drei-Schichten-Architektur für betriebliche Informationssysteme<br />

Für viele Anwendungen wird eine Drei-Schichten-Architektur gewählt. Diese besteht aus einer<br />

Benutzerschnittstelle, dem Anwendungskern und einer Datenbankschnittstelle.<br />

Benutzerschnittstelle:<br />

• Behandelt Nutzereingaben (Mausklicks, Tasten)<br />

• Ein-/Ausgabe von Daten<br />

• Dialogkontrolle<br />

Anwendungskern:<br />

• Zuständig für die Anwendungslogik, also die eigentlichen Aufgaben des Problembereichs<br />

• Ergibt sich aus dem Objektentwurf<br />

Datenbankschnittstelle:<br />

• Sorgt für Speicherung persistenter Daten der Anwendung und den Zugriff darauf<br />

Daneben gibt es noch Subsysteme für allgemeine Dienste, wie etwa Kommunikationsdienste,<br />

Dateiverwaltung oder Bibliotheken (APIs, GUI, …).<br />

2.3.5 Kontrollobjekte<br />

Für die Dialogsteuerung (z.B. Verwaltung mehrerer Fenster) oder zur Steuerung der Aufgaben des<br />

Anwendungskerns werden häufig eigene Objekte verwendet. Solche Kontrollobjekte sorgen für<br />

geringe Kopplung und haben meist ein interessantes Verhalten, das durch Zustandsdiagramme<br />

beschrieben werden kann.<br />

2.3.6 Beobachter<br />

Es gilt die Sichtbarkeitsregel zu beachten: Der Anwendungskern darf die Benutzerschnittstelle nicht<br />

kennen. Das hat den Vorteil, dass Änderungen an der GUI keine Auswirkungen auf den Code des<br />

Anwendungskerns haben. Um die berechneten Daten dennoch anzeigen zu können, kann man mit<br />

Beobachtern arbeiten.


12<br />

Indirekte Kommunikation durch Beobachter:<br />

• GUI-Objekte melden sich als Beobachter (Observer) beim Anwendungskern an (addObserver).<br />

• Falls der Anwendungskern ein Ereignis publizieren will, benachrichtigt er alle seine Beobachter<br />

(notifyObservers), die entsprechend reagieren (update).<br />

• Jeder konkrete Beobachter implementiert das Interface Observer.<br />

• Der Anwendungskern kennt (zur Programmierzeit) nur das Observer-Interface. Konkrete<br />

Observer werden zur Laufzeit dynamisch eingebunden.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!