|


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
|