____________________________Articles

 

 

 

Certification of Software Engineers

Early Start to Testing

Funktionen im Objektmodell?

Growing Internal Consultants

Litigation of Software-Intensive Projects

Measurable Requirements

On Death March Projects

O-O-Design: ganz einfach oder sehr kompliziert?

Performance in Organizations

Professionalism in Software Engineering

Requirements Patterns

Reusing the Products of Analysis

Setting the Context

Systems Architecture

UML: A Curse or Blessing? (pdf file)

Wer verträgt wieviel Abstraktion?

Wohin mit den Funktionen im Objektmodell?

 

 

Wohin mit den Funktionen im Objektmodell?

The following paper was originally published in Peter Hruschka's column on OO-analysis and design methods in "Objekt Spektrum 3/96". Here is an English abstract:

Where do we put the functions in an object model?


The question "What is an object?" is no longer asked today. Most people already know that objects are identifiable groups of data and functions (attributes and operations) that make up larger units.
The question we ask today is "How can a systems analyst find the right objects in a larger application?" When we have discovered many elementary attributes and many smaller and larger functions, how can we find their single best home? In other words, to which objects should we allocate the attributes and operations?


Wohin mit den Funktionen im Objektmodell?
Peter Hruschka

Das Geheimnis der Objektorientierung ist heute nicht mehr die Frage: Was ist ein Objekt? Es hat sich inzwischen herumgesprochen, daß Objekte die Zusammenfassung von Daten und Funktionen (Attributen und Operationen) zu größeren Einheiten sind.
Das Geheimnis ist heute eher: wie findet ein Systemanalytiker bei einer größeren Anwendung die richtigen Objekte. Oder mit anderen Worten: wenn wir in unserer Anwendung viele einzelne Attribute und viele kleinere und größere Funktionen entdeckt haben, wie finden wir dann für diese ihr richtiges Zuhause, d.h. das Objekt, dem sie am besten zugeordnet werden sollen?


Für die Attribute (d.h. die Datenelemente) fällt die Antwort vielen - vor allem gestandenen - Analytikern leichter als für die Funktionen. 20 Jahre Datenmodellierung hat uns gelehrt, mit Attributen und Entities umzugehen. Viele heute populäre OO-Analysemethoden haben ihren Ursprung mehr oder weniger in der Datenmodellierung. Coad/Yourdon bzw. Shlaer/Mellor sagen dies offen; aber auch bei OMT von Rumbaugh et al. ist der Einfluß deutlich sichtbar. Leihen wir uns doch einige Erkenntnisse aus der Datenmodellierung, um die Attribute richtig zu plazieren.
Angenommen, wir haben 500 Attribute gefunden. Wie teilen wir diese vernünftig auf Objekte auf? Für diese Fragestellung lehrt uns die Datenmodellierung, für jedes Attribut sein "SINGLE BEST HOME" zu suchen. Damit meinen wir den Platz in dem gesamten Objektmodell, wo dieses Attribut am besten aufgehoben ist (BEST HOME). Und auch den einzigen Platz, wo dieses Attribut sinnvoll zugeordnet werden muß (SINGLE HOME), um Redundanz zu vermeiden.
Die konstruktive Zuordnung während der Systemanalyse zu dem "single best home" wurde von Gary Schuldt geprägt. Sie garantiert einen hohen Grad an Wiederverwendbarkeit und Flexibilität bei Systemerweiterungen und Änderungen
Andere Datenmodellierer betreiben oft nachträglich (werkzeugunterstützt) Normalisierung. Einhaltung der 1. Normalform bedeutet, daß Attributgruppen oder wiederholte, mehrfache Attribute zu eigenständigen Objekten werden; die 2. und 3. Normalform überprüft, daß jedes Attribut eines Objekts vom Schlüssel und nur vom Schlüssel des Objekts ab hängt).

Wie aber ordnen wir Funktionalität den Objekten zu? Wo ist das SINGLE BEST HOME für unsere Operationen? Je kleiner und einfacher die Funktion ist, desto einfacher auch die Spielregeln. Wenn wir eine Objektklasse namens KONTO mit dem Attribut KONTOSTAND haben, dann wird wohl niemand anzweifeln, daß die Operationen "VERÄNDERE KONTOSTAND (um-Betrag)" und "LIES KONTOSTAND" zu dieser Objektklasse gehören.

Machen wir die Sache etwas komplizierter. Was ist, wenn die Operation auf mehreren Attributen arbeitet? Meine Beobachtungen in einigen Projekten hat gezeigt, daß dann bei vielen Systemanalytikern und Designern die alte Auftrennung von Daten und Funktionen wieder zuschlägt. Und dies wird oft durch gesundes Halbwissen über OO-Methoden noch gefördert. Hat nicht Ivar Jacobson vorgeschlagen, Objekte relativ bald in Entity-Objekte, Steuerungsobjekte (Control Objects) und User-Interface-Objekte zu kategorisieren, sobald wir einen Use-Case genauer betrachten?
Die folgenden Regeln sollen verhindern, daß man all zu schnell Steuerungsobjekte einführt, nur um ein Zuhause für eine Funktion zu haben. Diese Denkweise ist nicht nur wegen dem Modewort "Control Objects" sehr weit verbreitet, sondern vor allem, weil die die Methode Structured Design dies natürlich auch empfohlen hat: es gibt Systemteile, die Daten verwalten. Und diese werden durch andere Systemteile bearbeitet, die diese Daten miteinander in Verbindung bringen. Folgt man dieser Weltanschauung, dann ist man oft versucht, eine Operation, die nicht ganz eindeutig einem einzigen (Entity-)Objekt gehört, sofort als Steuerungsobjekt zu modellieren und auf alle Entity-Objekte, die benötigt werden, zuzugreifen. Das dies oft nicht notwendig ist, soll die folgende Fallunterscheidung zeigen.

Fall 1) Eine Funktionen arbeitet auf mehreren Attributen eines Objekts. In diesem Fall sollte die Funktion natürlich noch immer bei der Objektklasse bleiben. Alles ist lokal bei dem Objekt beschreibbar. Ein Beispiel wäre die Historienführung des Kontostandes. Betroffen sind 12 Kontostände, jeweils am Monatsende eines kompletten Jahres, für die der Mittelwert berechnet werden soll.

Fall 2) Eine Funktionen arbeitet auf Attributen von mehreren Objekten derselben Klasse. In der Analyse besteht immer noch keine Veranlassung, die Funktion anderswo zu plazieren als bei der Objektklasse. Rumbaugh schlägt vor, diese aber als Klassenoperationen zu kennzeichnen und damit von Fall 1 unterscheidbar zu machen. Ein Beispiel wäre eine Funktion, die für alle Konten den Durchschnittswert des Kontostandes an einem Stichtag ermittelt.

Fall 3) Eine Funktionen arbeitet auf Attributen verschiedener Objekte verschiedener Klassen. Jetzt wird es langsam interessant und wir sollten die Funktion genauer untersuchen.

Fall 3a) Die Funktion hat die Form y = f(a), wobei die Eingabe a ein Attribut eines Objekts und die Ergebnis y Attribut eines anderen Objekt ist. Jetzt haben Sie die Qual der Wahl: eingabe- oder ergebnisorientierte Zuordnung. Eingabeorientiert heißt, die Funktion ist dem Objekt zugeordnet, zu dem das Attribut a gehört, rechnet dort und teilt das Ergebnis zum Schluß dem anderen Objekt mit ("Push"). Ergebnisorientiert heißt, das Objekt mit dem Attribut y hat auch die Funktion und holt sich die benötigte Eingabe ("Pull") von dem anderen Objekt. Meine Präferenz ist oft "Push", d.h. eingabeorientierte Zuordnung, insbesondere, wenn das Eingabeattribut Schlüsselcharakter hat. Die Entscheidung ist aber oft willkürlich. Auf keinen Fall aber sollte die Einführung eines dritten Steuerungsobjekts als Zuhause für diese Funktion erwogen werden.

Fall 3b) y = f(a,b,c), d.h. die Funktion hat viele Eingaben, evtl. aus unterschiedlichen Objekten, aber nur ein Ergebnis. In diesem Fall lohnt sich eine ergebnisorientierte Zuordnung. Die Funktion gehört zu dem Objekt mit dem Ergebnis und holt sich seine Eingaben ("Pull"). Beispiel: Startnummer ist das Ergebnis der Funktion Wettkampfanmeldung. Eingaben sind u.a. Name, Vorname, Alter und Teamzugehörigkeit eines Teilnehmers, aus dem Wettbewerb der Ort und das Datum, etc. Diese Funktion sollte dem Objekt zuordnet werden, das die Startnummer als Attribut enthält, d.h. bei "Anmeldung". Im Lauf der Zeit finden sich für dieses Objekt vielleicht weitere Attribute, die derzeit noch gar nicht gebraucht werden, wie z.B. das Anmeldedatum zur <berprüfung, das nur die ersten 50 Teilnehmer, die sich angemeldet haben, zugelassen werden. (Anmerkung: diese neue Funktion "prüfe <berlauf" ist gemäß Fall 2 eine Klassenoperation auf Anmeldung).

Fall 3c) x,y,z = f(a), d.h. die Funktion erzeugt viele Ausgaben evtl. in unterschiedlichen Objekten aus einer Eingabe. Solche Funktionen sollten bevorzugt eingabeorientiert plaziert werden ("Push"), dann kann die Funktion als eine Einheit zusammengehalten werden. Die Alternative wäre, die Funktion in drei Funktionen zu zerlegen und ergebnisorientiert zuzuordnen ("Pull"): Dadurch geht u. U. der logische Zusammenhalt der Funktion verloren. Wie schon oben erwähnt ist die Einführung eines zusätzlichen Steuerungsobjekts für die Funktion die Lösung, die am wenigsten angestrebt werden sollte.

Als Zwischenzusammenfassung kann man festhalten: Solange Eingabe oder Ergebnis der Funktion einfach sind (d.h. in der Verantwortung eines Objekts liegen), kann man die Funktion noch gezielt zuordnen, ohne neue Objekte schaffen zu müssen.

Fall 4) Komplexere Funktionen, wie man sie typischerweise bei Anwendung der Methode "Strukturierte Analyse" in höheren Ebenen findet oder Funktionen, die einen ganzen Geschäftsprozeß beschreiben, wie man sie durch Use Cases modelliert, sind die ersten Kandidaten für die eventuelle Auslagerung von Steuerungsanteilen. In unserer Darstellung von oben wären das Funktionen mit x,y,z = f(a,b,c,d): die Funktion ist gekennzeichent durch mehrere Eingaben, viele Ausgaben und eventuelle Seiteneffekte wie Zustandsänderungen, etc.
In solchen Fällen schlägt Ivar Jacobson vor, für die Funktion ein Steuerungsobjekt einzuführen. Aber Vorsicht: lesen Sie weiter und denken Sie weiter. Die Funktion, die diesem Steuerungsobjekt zugeordnet wird ist nicht die komplette Ausführung der beschriebenen Aufgabe oder des Geschäftsprozesses. Solch komplexe Funktionen haben große Anteile, die nach den obigen Regeln 1 - 3 einzelnen anderen Objekten übertragen werden können. (Delegation von Teilaufgaben!). Nur der Rest, der Klebstoff der Teilaufgaben, die generelle Ablaufsteuerung im Großen, verbleibt bei dem Steuerungsobjekt.

Vieles gäbe es noch über die Zuordnung von Funktionen zu Objekten zu sagen. Weitere Regeln können aufgestellt werden, wenn man neben bisherigen Kriterien auch noch die Aufgabenstellung der Funktion mitberücksichtigt: z.B. Funktionen zum Berechnen von Attributen unterscheidet von solchen, die Beziehungen aufbauen, abbauen oder modifizieren. Oder wenn man die Häufigkeit und die Komplexität des Zugriffs berücksichtigt. Dies würde jedoch den Umfang dieser Kolumne sprengen.

Die Moral von der Geschichte: Auch wenn Sie gehört oder gelesen haben, daß neben Entity-Objekten jetzt auch Steuerungsobjekte "hoffähig" geworden sind, nutzen Sie diese bitte vorsichtig. Versuchen Sie möglichst lange, die Operationen bei den Objekten zu plazieren und isolieren Sie nur solche Teile von Vorgängen oder Geschäftsprozessen, die den Zusammenhalt zwischen diesen angereicherten Entity-Objekten betreffen. Ein zu heftiges Herauslösen von Funktionen in viele Steuerungsobjekte widerspricht der Grundidee der Kapselung und führt zu weniger wartbaren und pflegbaren Systemen.


Biographie:
Dr. Peter Hruschka ist unabhängiger Trainer und Methodenberater mit Schwerpunkt Objektorientierung und Embedded Real-Time Systems. Er ist Autor, Herausgeber und <bersetzer mehrerer Bücher und zahlreicher Artikel im Bereich Software-Entwicklungsmethoden und CASE. Fax: 0241- 96 21 50 oder E-Mail Adresse:
phruschka@compuserve.com


 

top of page