Noch gibt es Hürden auf der "Prachtstraße zum Software-Entwurf", Teil 3

Objektorientiertes Design - die Realisierung des Machbaren

30.08.1991

Ideale Ergebnisse gibt es nur unter idealen Bedingungen. Das gilt auch für die objektorientierte Entwicklung (OOP). Wer sich von der Objektorientierung ein Allheilmittel gegen seine "organisch gewachsenen" DV-Altlasten erhofft, wird enttäuscht werden. In der letzten Folge unserer kleinen OOP-Serie geht es um die Möglichkeiten und Grenzen für objektorientiertes Design im wirklichen Leben.

Manchmal wird die Frage gestellt, ob denn bei Objektorientierung die Differenzen zwischen Analyse, Design und Programmierung nicht verschwänden. Eigentlich scheint doch alles schon fertig: Ein Objekt wird ein Objektmodul, das heißt ein Exemplar (Instance) einer Klasse, die von einer Oberklasse (Abstraktion) einige Attribute (Variables) geerbt hat (Inheritance), welche mit Prozeduren (Methoden) zusammengeschlossen sind (Encapsulation).

Falls man das Design erstens auf einer Tabula rasa und zweitens ohne weitere Bedingungen (Sicherheit, Recovery, Geschwindigkeit) mittels Smalltalk oder Eiffel realisiert, ist das (fast) richtig. Man muß allerdings bedenken, daß man es auf der Ebene der Programmierung zunächst mit sehr abstrakten Objekten zu tun hat (zum Beispiel Integer, Punkt, Rechteck).

Falls allerdings in einem existierenden Getriebe unter einer Vielzahl von Rahmenbedingungen durch die Einführung des Konzepts der Objektorientierung die Produktivität gesteigert werden soll, so existiert eine tiefe Kluft zwischen OOA und OOD. Ging man in der Analyse vom sachlichen Problembereich aus, dem "Was", so geht es in der Designphase um die DV-technische Umsetzung, um das "Wie".

Betrachten wir einen Augenblick das Objekt "Drucker".

Unter Analyse-Gesichtspunkten könnten hier wichtig sein:

- die Qualitätsauswahl,

- der Ausgabeort (bei Systemen mit mehreren Druckern, Poststraße etc.) sowie

- die Geschwindigkeit.

Unter dem Gesichtspunkt des Designs betrachtet man von vornherein ein System von Objekten und interne Probleme wie

- Queue-Management,

- Routing,

- Integration (Advanced Function Printing, Postscript),

- Verteilung der für die Dokumenterstellung notwendigen Daten.

Diese prinzipielle Differenz zwischen Analyse und Design wird hinsichtlich der Entwicklung von Anwendungen für Großsysteme noch durch eine große Zahl von keineswegs objektorientierten Standardservices vergrößert, die berücksichtigt werden müssen. Nehmen wir eine kommerzielle Applikation aus der MVS-Welt, so haben wir es im Minimum zu tun mit

- einem Sicherheitssystem (etwa RACF),

- einem Transaktionsmonitor (beispielsweise CICS),

- Kommunikationssoftware (zum Beispiel VTAM) sowie

- einem Datenbanksystem (etwa IMS).

Diese schwierige Lage wird dadurch komplettiert, daß meines Wissens für MVS noch gar kein OO-Compiler existiert.

Stellt man diese Situation in Rechnung, so ist klar, daß es keine einfache und allgemeingültige Antwort auf die Frage "Was ist OOD?" geben kann.

Ich skizziere im folgenden in aller Kürze an einem Beispiel meinen Vorschlag, wie man im Rahmen kommerzieller Informationsverarbeitung OOD betreiben könnte, um die Wartbarkeit und Sicherheit der Systeme und die Wiederverwendbarkeit von Design und Code zu erhöhen.

Ich gehe von drei Voraussetzungen aus:

- Erstens wurde eine "OO"-Analyse erstellt. Dieser steht ja prinzipiell nichts im Weg - außer der Gewohnheit der Anwendungsentwickler.

- Zweitens unterstelle ich eine relationale Datenbank. Das ist nicht notwendig (eine klare Schnittstelle reicht aus), aber es dient der Vereinfachung und scheint mir sinnvoll, da relationale Datenbanksysteme sich vermutlich weiter durchsetzen werden.

- Drittens setze ich einen PC als Front-end voraus, so daß Verbundverarbeitung betrieben werden kann. Dies ist zum einen realistisch, zum anderen vereinfacht es das Problem, da für PCs echte OO-Entwicklungsumgebungen existieren.

Betrachten wir als Beispiel einen Teil einer Versicherungsanwendung. Dieses System soll in folgender Situation dem Mitarbeiter einer Versicherung Hilfestellung bieten: Herr Zip möchte eine Lebensversicherung abschließen. Unser Mann von der Versicherung interessiert sich zunächst für Herrn Zips Versicherungsbestand. Er ruft das Bildschirm-Objekt "Versicherungsnehmer" (VN) auf und verlangt das Objekt "Zip".

Nun muß das Exemplar "VN (Zip)" gebildet werden. Im Set seiner Methoden muß "Anzeigen (zugehörige Versicherungen)" enthalten sein. Das sagt uns die Analyse.

Vom Design-Standpunkt stellt sich die Lage so dar: Dem Modul (Klasse VN) wurde die Nachricht zur Exemplarbildung - also etwa (VN, Instantiate, Zip) - vom Dialogfenster-Objekt gesendet. Dieses hatte zunächst seine Methode "Prüfen" angewendet, um Formfehler zu entdecken (Zahlen im Namen etc.).

VN (Zip) erhält nun eine Nachricht, um zu veranlassen, daß die Liste der übrigen Versicherungen von Herrn Zip gezeigt wird, etwa (VN (Zip), Anzeigen, Verträge). Vermutlich kennt VN (Zip) die Verträge zunächst gar nicht. Diese werden nämlich sicher nicht auf dem PC gespeichert, sondern auf einem Server beziehungsweise zentral auf dem Host. Nehmen wir letzteres an, dies ist der Normalfall.

VN (Zip) muß sich die Werte, die zu seiner Datenbasis gehören und für die Variablen definiert sein müssen, durch eine Kommunikation mit Host-Objekten erst besorgen. Man kann sich den Vorgang wie eine schrittweise Instantiierung vorstellen, die dadurch bedingt ist, daß es keinen Sinn ergibt, alle Daten, die unter Umständen gebraucht werden, lokal zu speichern.

Der Sinn des Designs der Klasse VN besteht darin, für alle Probleme, die den Versicherungsnehmer betreffen, mit Exemplaren wie VN (Zip) ein fixes Protokoll zur Verfügung zu stellen. Vom Standpunkt einer eventuellen Weiterverarbeitung solcher Informationen durch andere Objekte auf dem PC sind sämtliche Implementationsschritte, die nun diskutiert werden, unsichtbar (Information Hiding).

Um zu seinen Werten zu kommen, könnte VN (Zip) eine Nachricht an eine Partnerklasse HVN auf dem Host senden. Dieses Programm müßte alle Daten verarbeiten können, die im Zusammenhang mit dem Versicherungsnehmer wichtig sind. Das heißt, es enthielte als Methoden alle Transaktionen, die die entsprechenden Datenbankzugriffe steuern, also auch die zum Auflisten der Verträge von Zip. Als Implementierung handelte es sich um ein Unterprogramm des Transaktionsmonitors, das, abhängig von den beim Aufruf übergebenen Parametern, entsprechende Transaktionen startet, deren Ergebnisse übernimmt und weiterreicht - zum Beispiel an VN (Zip).

Betrachten wir nun den Fall, daß Herrn Zips Antrag eingegeben werden soll. Es wird das Bildschirm-Objekt "Vertrag" aufgerufen. Zu seinen Methoden gehört "Neuanlage". Es wird also auf dem PC ein Objekt Ver (Zip) geschaffen, das in der Lage ist, die notwendigen Daten aufzunehmen. Die Variablen würden durch entsprechende Nachrichten vom Dialogfenster-Objekt gefüllt.

Zur wirklichen Neuanlage gehört aber eine komplizierte Prüfung, ein Update der juristischen Bestände und vieles andere mehr (zum Beispiel das Drucken und Versenden des Vertrages). Prüfung und Update müssen unter unseren Voraussetzungen auf dem Host stattfinden. Es würde sich empfehlen, von Ver (Zip) eine Nachricht an ein Host-Objekt "Prüfung" zu senden, und zwar mit den Größen (Vertrag (Leben), Neuanlage, Zip).

Starke Isolierung und stabiles Protokoll

Die Oberklasse "Prüfung", die virtuell die für solche Prüfungen notwendigen Daten und verschiedene generelle Prüfmethoden (zum Beispiel für Änderungen und Kündigungen) enthält, ruft nun eine Subklasse "Prüfung für Lebensversicherung" (PLV) auf, der die Methode für Neuanlagen zur Verfügung steht. Das Objekt PLV (Zip) ist nun ein Exemplar dieser Klasse, welches die Methode für Neuanlage geerbt hat. Vom Standpunkt der Implementation handelt es sich bei "Prüfung" um ein Steuerprogramm, das - abhängig von den übergebenen Parametern - ein weiteres Steuerprogramm für den konkreten Fall - in unserem Fall PLV - aufruft, das dann die notwendigen Transaktionen zur Datenbeschaffung und Berechnung aufruft beziehungsweise andere Steuerprogramme benachrichtigt, falls Daten gebraucht werden, die zu anderen Objekten (zum Beispiel VN oder Inkasso) gehören. Man erreicht so eine starke Isolierung der Implementation der verschiedenen Objekte und ein stabiles Protokoll gegenüber den Objekten, die die Resultate weiterverarbeiten.

Weichen für die Dekade werden heute gestellt

In unserem Beispiel könnte PLV (Zip) mit der Nachricht an Ver (Zip) reagieren, daß eine Neuanlage unmöglich ist, weil Herr Zip noch nicht einmal die bestehenden Versicherungen bezahlt - etwa: (Ver (Zip), zurückweisen, zahlt nix). Hier wäre "zurückweisen" eine Methode, die den Parameter "zahlt nix" in höflicher Weise verarbeiten kann. -

Falls jedoch alles in Ordnung ist, könnte PLV (Zip) an das Host-Vertragsobjekt HVer eine Nachricht senden, die die Neuanlage auslöst, etwa (HVer, Anlegen, Zip, LV, Versicherungssumme ...). Hier würde nun die Methode "Anlegen" die nötige SQL-Befehlsfolge absetzen, um die Datenbank mit den juristischen Beständen zu aktualisieren. Außerdem müßten verschiedene Nachrichten an andere Objekte versendet werden wie Bestätigung an Ver (Zip), Zusatzeintrag bei HVN etc. Gehen wir noch einmal die OO-Essentials durch.

- Encapsulation, Abstraction und Information Hiding: Sie waren die Designprinzipien.

- Inheritance: Man erinnere sich an "Prüfung". In einem System, in dem mehrere Versicherungsarten verwaltet werden, also etwa Kfz-, Unfall- und Lebensversicherung, sind manche Teile der Prüfungen gleich (etwa die Kontenbetrachtung). Diese Teile werden vererbt, indem die Transaktionen in die einzelnen Spartenprüfungsmethoden übernommen werden. Was die Daten betrifft, so handelt es sich bei HVer beispielsweise um eine Supraklasse, die alle Attribute enthält, die den verschiedenen Versicherungsvertrags-Arten gemeinsam sind. Hier liegt eine Schnittstelle zum Datenbankdesign, und es wird klar, wie hilfreich ein Entity-Relationship-Design mit Sub- und Supra-Entitäten sein kann.

- Polymorphismus: Man kann durchaus die Nachrichten - etwa zum Auflisten der Versicherungsfälle des letzten Quartals - identisch gestalten, auch wenn es um unterschiedliche Sparten geht. Je nachdem, ob das Objekt Schaden (Kfz) oder Schaden (Hausrat) sie erhält, werden eben ganz unterschiedliche Transaktionen gestartet.

Zusammenfassend kann gesagt werden, daß solch ein Design, das übrigens durch das Konzept der "eingebetteten Transaktionen" (nested transactions; vgl. Mullender (Herausgeber), Distributed Systems, Reading 1989) stark unterstützt würde, sicher die Schnittstellen verbessern und die Isolierung der Module erhöhen würde. Somit ist das System besser wart- und erweiterbar.

Man könnte die Sicherheit verbessern, indem nur den fixierten Methoden Update-Zugriff auf die Datenbank gegeben würde. Außerdem würde die Wiederverwendbarkeit auf Transaktionsniveau erhöht - darunter freilich nicht. Hier greift erst Inheritance im Sinne von OOP.

Vom Standpunkt eines MVS-Shops scheint es mir außerordentlich wichtig, zu einem Entschluß über die Bedeutung zu kommen, die man der Objektorientierung geben will. Heutzutage werden in den Abteilungen für Anwendungsentwicklung die Weichen für eine ganze Dekade gestellt. Diese Festlegung zementieren noch die Investitionen in CASE-Werkzeuge. Diese sind nämlich keineswegs so methodenneutral, wie sie auf Marketing-Niveau dargestellt werden.

Es handelt sich bei Objektorientierung nicht um eine bloße Mode, die ohnehin bald uninteressant ist. Genausowenig allerdings ist OO der Deckel, der auf alle Töpfe paßt, wie die Philosophen glauben machen wollen.

Meines Erachtens ist es hier und jetzt sinnvoll, die IS-Services für Geschäftsprozesse dingfest zu machen, die durch eine flexiblere und komfortablere Oberfläche am meisten gewinnen würden. Diese Arbeitsplätze sollten mit einer grafischen OO-Benutzeroberfläche ausgestattet werden.

Natürlich ist es ein langer Weg, bis alle Objekte realisiert sind. Aber er wird durch Abwarten nicht kürzer. Bei der Neuerstellung der Applikationen sollte OOA angewendet werden. Literatur gibt es genug. Also ist es eine Frage der Ausbildung. Einen möglichen Weg für OOD habe ich angedeutet - er wird zur Zeit für ein Buch ausgearbeitet.

In bezug auf die Implementierung scheint mir OOP für den auf dem PC laufenden Front-end-Teil der Anwendung richtig. Die Host-Transaktionen sollten nach OOD-Prinzipien in einer gewöhnlichen Programmiersprache produziert werden.

Ich bin mir bewußt, daß hier mit sehr starken Vereinfachungen argumentiert wurde, aber die Planung der Einbeziehung solch moderner Trends wie Objektorientierung in eine bestehende DV-Landschaft kann nur Resultat einer konkreten Analyse der spezifischen Situation sein. Wer auf einer Tabula rasa beginnen kann, hat es da natürlich erheblich leichter.

Dr. Michael Peltzer ist Berater bei der IBM Unternehmensberatung für Informationsmanagement in Hamburg.