Beispiel zur Musteridentifikation

Kontrolle des Ablaufs (Observer)

Die Separierung des Subsystems, das für die Interaktion mit SAP-R/3 zuständig ist von dem, das Gleiches für die OSA-Seite übernimmt, war ein wichtiger Anspruch im Rahmen der Entwicklung des OSA-Servers. Nur so kann der leichte Austausch der Interoperabilitätsschnittstelle (in diesem Fall OSA) gewährleistet werden. Die Entkopplung der Subsysteme ist für den Daten- wie auch für den Kontrollfluß nötig. Auf den Kontrollfluß, d.h. die Reaktion auf einen OSA-Aufruf, werden wir in diesem Beispiel näher eingehen.

Anhand eines Ausschnitts aus dem Entwurf ist in Schritt 1, oben das generelle Problem dargestellt: Wie wird der Kontrollfluß zwischen dem Empfänger der Nachricht (OSADispatch) und der Klasse, die die Komponente des SAP-Systems repräsentiert (BOR - Business Object Repository) geregelt? Zur Orientierung eine Aufstellung der Anforderungen:

Die 1:n-Relation zwischen den Subsystemen ist als Erweiterung der Anforderungen der Analyse einzuordnen; die anderen Anforderungen sind Verbesserungen des Entwurfs zur Steigerung der Flexibilität. Die Anforderungen induzieren weitere indirekte. Beispielsweise wird die Kommunikation zwischen den Klassen verallgemeinert werden müssen, um der Forderung der Austauschbarkeit gerecht werden zu können.

Um das Entwurfsproblem zu lösen, kommen zunächst mehrere Muster in die engere Wahl [5]:

Die Auswahl unter den in Frage kommenden Mustern ist der wichtigste Schritt, da alle folgenden Transformationen des bestehenden Entwurfs und die Qualität des Endergebnisses davon abhängen. Eine Entscheidung kann der Entwerfer nur auf der Basis seines Musterwissens und der Kenntnis der Anforderungen aus der Problemdomäne fällen. Ein vertieftes Verständnis für das Potential, die Essenz eines Musters kann nur durch dessen (mehrfachen) konkreten Einsatz erlangt werden. In Schritt 1, unten ist die Essenz des Observer-Musters dargestellt:

Ein Hinweis für die unzureichende Eignung von Facade und Adapter ist deren primäre Eigenschaft als strukturierendes Muster ([5], S.10). Im konkreten Fall steht die Steuerung des Verhaltens (der Kontrollfluß zwischen OSADispatch und BOR) eindeutig im Vordergrund. Chain of Responsibility ist insofern ungeeignet, als daß dessen Essenz darin besteht, daß Objekte einen Aufruf entlang ihrer Klassenhierarchie weiterleiten können. Die Klassen der Subsysteme nur aus dem Grund, ein Muster einsetzen zu wollen, in eine semantisch nicht begründbare Vererbungsbeziehung zu stellen wird höchstwahrscheinlich nicht von Erfolg gekrönt sein. Das Observer&endashMuster hat sich als das geeignetste erwiesen; die Übertragung dieses Musters in den konkreten Entwurf werden wir im Folgenden beschreiben.

 

examp2_0.jpg (72794 byte)

Schritt 1: Identifikation eines Musterkandidaten im Entwurf

Ausgangssituation ist also das einfache Vorgehen des direkten Aufrufs der Methoden der Klasse BOR nach dem Empfang eines Events durch OSADispatch. BOR nimmt die Rolle des Servers, OSADispatch die des Client ein. Nachteilig an diesem Vorgehen ist, daß die Verantwortlichkeit bei OSADispatch liegt, was den Ablauf der Kommunikation und die Auswahl unter ggf. mehreren SAP-Systemen angeht. Ebenfalls konträr geht dieser Ansatz mit dem Prinzip, daß die Client-Komponente sich mit um so geringerem Aufwand gegen eine andere austauschen läßt, je leichtgewichtiger sie ist. Flexibler und dem Framework-Gedanken (don't call us, we call you) entsprechend, ist der umgekehrte Weg: OSADispatch und BOR tauschen die Rollen und die Kommunikation findet in der umgekehrten Richtung statt (Schritt 2, unten). OSADispatch fungiert nun als Server und gibt nach einem Nachrichtenempfang lediglich die Meldung weiter, das sich etwas verändert hat (Notify()). Die als Klienten bei Subject angemeldeten SAP-Systeme erhalten die Änderungsnachricht (Update()) und entscheiden selbsttätig, wer gemeint ist; anschließend werden bei OSADispatch die zusätzlichen Informationen abgerufen (GetCommand()).

examp2_1.jpg (54046 byte)

Schritt 2: Zuordnung der Entwurfskomponente auf das Muster

In Schritt 2 wurde deutlich, daß die Funktionalität der Klasse BOR (die Operationen Create(), Delete() und Invoke()) der Musterfunktionalität nicht zugeordnet werden konnte. Statt dessen wird, wie in Schritt 3 ersichtlich die Klassenschnittstelle von BOR verändert. Die bisherigen Operationen können nicht mehr direkt angesprochen werden (sie werden zu protected members); deren Aufruf erfolgt indirekt über den Aufruf von Update(). BOR steuert sich nach Aufforderung (Notify()) somit selbst.

examp2_2.jpg (50576 byte)

Schritt 3: Strukturelle Änderungen im Entwurf

Bei diesem Ansatz liegt die Verantwortlichkeit für den Ablauf eindeutig bei dem als unveränderlich klassifizierten SAP&endashSubsystem. Die 1:n&endashRelation ist durch das Muster in den Entwurf "quasi nebenbei" eingeführt worden.

Um der Anforderung nach leichter Austauschbarkeit von OSADispatch gerecht zu werden, müßte die Musterausprägung als Framework realisiert werden. Hierzu würde ein abstrakter Nachrichtenverteiler (AbstractDispatch) eingeführt, mit dem ein Kommunikationsprotokoll für die Übergabe der zwischen BOR und AbstractDispatch ausgetauschten Nachrichten definiert wird. Bisher übernimmt diese Kommunikation die eher symbolisch zu verstehende Operation GetCommand(). Konkrete Verteiler, wie OSADispatch würden von AbstractDispatch und von Subject abgeleitet. Für die Übersetzung eines Kommunikationsprotokolls könnte in diesem Zusammenhang das Adapter-Muster eingesetzt werden.

Die bis hier beschriebenen Schritte lassen erkennen, daß der ursprüngliche Ansatz flexibilisiert und die Verantwortlichkeiten durch die Musterausprägung stark verschoben wurden; die mögliche Weiterentwicklung hin zu einem Framework ist vorgezeichnet.

Zum Schluß noch die Einführung der technischen Klassen in den Entwurf:

examp2_3.jpg (55667 byte)

Schritt 4: Die Einführung der technischen Klassen



© 1997, Universität-GH Siegen, Technische Informatik, Georg Odenthal und Klaus Qu ibeldey-Cirkel