Implementierung von JWI anhand des UML-Modells

 

 

1. Allgemeiner Aufbau des Programms

Das Programm besteht aus 22 Dateien in denen die 25 Klassen und das Hauptprogramm – in der Datei "JWI_Hauptprogramm.cpp" – implementiert sind.

Der nachfolgenden Aufstellung kann entnommen werden, welche Datei welche Klassen enthält:

"JWI_Klassen_Bestellposten.h" und "JWI_Klassen_Bestellposten_Implementation.cpp" -> Klassen "Bestellposten", "BestellpostenListe", "Lieferkartei" und "Wartekartei"
"JWI_Klassen_Bestellung.h" und "JWI_Klassen_Bestellung_Implementation.cpp" -> Klassen "Bestellung", "Kundenbestellung", "Nachbestellung", "NachbestellungenKartei" und "KundenbestellungenKartei"
"JWI_Klassen_Geschaeftspartner.h" und "JWI_Klassen_Geschaeftspartner_Implementation.cpp" -> Klassen "Geschaeftspartner", "Kunde", "Lieferant", "KundenKartei" und "LieferantenKartei"
"JWI_Klassen_Lieferschein.h" und "JWI_Klassen_Lieferschein_Implementation.cpp" -> Klassen "Lieferschein" und "LieferscheinListe"
"JWI_Klassen_Produkt.h" und "JWI_Klassen_Produkt_Implementation.cpp" -> Klassen "Produkt" und "ProduktKartei"
"JWI_Klassen_Verwaltung.h", "JWI_Verwaltung_BestellungAnnehmenUndBearbeiten_Implementation.cpp", "JWI_Verwaltung_FehlbestaendeNachbestellen_Implementation.cpp", "JWI_Verwaltung_LieferscheineErstellen_Implementation.cpp", "JWI_Verwaltung_private_Implementation.cpp", "JWI_Verwaltung_public_Implementation.cpp", "JWI_Verwaltung_RuecklaufBearbeiten_Implementation.cpp" und "JWI_Verwaltung_WareneingangBearbeiten_Implementation.cpp" -> Klasse "Verwaltung"
"JWI_Klassen_Datum.cpp" -> Klasse "Datum"
"JWI_Klassen_Fenster.cpp" -> Klassen "BildschirmFenster", "Menue", "EingabeFenster" und "AusgabeFenster"
"JWI_Klassen_Liste.cpp" -> Klasse "Liste"

Dem Hauptprogramm kommt dabei die Aufgabe zu, die den Programmablauf steuernde Klasse Verwaltung durch den Programmstart zu initialisieren. Anschließend stellt es ein Menü zur Verfügung, aus dem die jeweils nächste Aufgabe, die das Programm auszuführen hat, ausgewählt wird. Somit stellt das Hauptprogramm lediglich eine Schnittstelle zwischen dem Benutzer, der die einzelnen Programmfunktionen (Anwendungsfall) anstößt, und dem restlichen Programm dar.

Ähnlich wie das Hauptprogramm stellen außer der Klasse Verwaltung alle weiteren Klassen Hilfsfunktionen zu Verfügung: in ihnen werden Objekte definieren, die in der Klasse Verwaltung zusammengeführt und benutzt werden. In diesem Zusammenhang sei insbesondere auf die Klassen "Datum", "Liste" und "Bildschirm-Fenster" hingewiesen, die erst bei der Implementierung zum Klassenmodell neu hinzugekommen sind (vgl. altes Klassenmodell). Sie sind bei einer wirklichen Umsetzung an die Implementatierungsumgebung anzupassen. Weiterhin sei angemerkt, das diese Klassen ausschließlich Hilfsklassen für die fachlichen Klassen "Bestellposten", "Bestellung", "Lieferschein", "Geschäftspartner", "Produkt" und "Verwaltung" und die aus ihnen abgeleiteten Klassen sind. Aufgrund dieses Hilfsleistungscharakters sind sie nur grob und in Ansätzen implementiert. Die restlichen Klassen des Modells sind entweder nahezu vollständig ausprogammiert , oder es existiert in einigen Operationen ein Verweis auf eine entsprechende Operation (mit ähnlicher Funktion), die ausprogrammiert ist.

Es soll noch die Hilfsklasse Liste hervorgehoben werden, die für die Verwaltung und Speicherung von Elementen jeweils eines bestimmten Typs zuständig ist. Durch den gewählten Template-Ansatz ist es möglich aus jeglicher Art von Elementen eine Liste zu erzeugen. Deshalb werden die Klassen Lieferkartei und Wartekartei des ursprünglichen Modells nicht mehr benötigt (vgl. 5.7 Die Klasse Liste). Daß diese Klassen trotzdem in der Implementierung enthalten sind und nicht nur – im Verlauf des Programms – durch eine Instanz der Klasse Liste erzeugt werden soll andeuten, daß diese Listen durch Operationen erweitert werden können, die die in ihnen enthaltenen Daten extern speichern und nur die direkt benötigten Objekte im aktuellen Speicher behalten. Daher werden sie auch in diesem Modell als "Karteien" bezeichnet. Der Gleiche Grund steckt hinter der Definition der Klassen "Nachbestellungen-Kartei", "Kundenbestellungen-Kartei", "Kunden-Kartei", "Lieferanten-Kartei" und "Produkt-Kartei". Alle zur Laufzeit benötigten Objekte dieser Klassen werden von einem Objekt der Klasse Verwaltung verwaltet.

Wie aus dem Bisherigen hervor geht kommt dem Objekt der Klasse Verwaltung die Aufgabe zu, die übrigen Objekte in Listen zu speichern und zu verwalten, ihre Informationen zu verknüpfen und die durch die Anwendungsfälle definierten Programmabläufe bereitzustellen. Mit Ausnahme der Anwendungsfälle "Bestellung annehmen" und "Bestellung bearbeiten", die zusammengefaßt worden sind, besitzt jeder der im JWI-Modell definierten Anwendungsfälle, eine eigene Operation in der Klasse Verwaltung und einer eigenen Datei zur ihrer Implementierung (für die Dateien vgl. obige Aufstellung der Dateien und Klassen). Diese Implementationen sind nahezu vollständig. Die Zusammenfassung der beiden Anwendungsfälle "Bestellung annehmen" und "Bestellung bearbeiten" ist die einzige Veränderung, der Anwendungsfälle des ursprünglichen Entwurfs. Der Grund dafür war, daß die für den Anwendungsfall Bestellung bearbeiten notwendigen Daten durch Bestellung annehmen zur Verfügung gestellt werden und Bestellung bearbeiten dann ausschließlich Programm intern abläuft, d.h. es werden keine weiteren Eigaben des System-Benutzers benötigt. Außerdem hätte die Teilung der beiden Anwendungsfälle beim Aufruf von Bestellung bearbeiten dazu geführt, daß die zugehörige Bestellung neu gesucht werden müßte, was eine unnötige Bildschirm-Eigabe des Benutzers erforderlich gemacht hätte.

 
 

2. Zusammenhang der einzelnen Progamm-Dateien 

Abbildung 1 gibt die Struktur, in der die einzelnen Dateien des Programms zusammengeführt worden sind wieder. Dabei ist zu beachten, daß eine Datei A, die in einer weiteren Datei B inkludiert ist auch automatisch in alle anderen Dateien C inkludiert wird, die die Datei B inkludieren. Somit stehen die Deklarationen bestimmter Dateien in anderen Dateien zur Verfügung, die nicht direkt im Diagramm verbunden sind. Einige dieser impliziten Inklusionen sind für das Programm notwendig und somit gewollt.

Außerdem sollte darauf hingewiesen werden, daß in Inklusion der Klasse Liste in die Dateien der Klasse Produkt bzw. der Klasse Geschäftspartner nur notwendig ist, um die, Definitionen der abgeleitete Klassen Produkt- bzw. Kunden- und Lieferanten-Kartei, in diesen Dateien durchführen zu können. Somit ist diese Inklusion unnötig, wenn anders implementiert wird (z.B. mit einer weiteren Datei).

 

 

3. Veränderungen des neuen Klassen-Modells gegenüber dem ursprünglichen

Wie in Paragraph 5. zur Implementation der einzelnen Klassen genauer beschrieben wird, sind durch die Implementation nicht unerhebliche Neuerungen am Klassen-Modell entstanden. Neben den drei Hilfsklassen Liste, Datum und Bildschirm-Fenster, die neu hinzugekommen sind wurden andere Klassen zu Oberklassen zusammengefaßt (Bsp. Klasse Bestellung) und aus Oberklassen abgeleitete Klassen (Bsp. Klasse "Kunden-Bestellposten") weggelassen.

Ein durch die Implementation neu gebildete Klassenmodell befindet sich in Abbildung 2 (vgl. altes Klassen-Modell). Um das Diagramm, die bedeutend mehr Klassen als das alte Modell enthält nicht unnötig unübersichtlich zu gestalten, wurden die Beziehungen zu den drei Hilfsklassen im Diagramm nicht weiter erläutert. Die vorliegende Beziehung ist jeweils, daß lediglich ein Objekt der jeweiligen Hilfsklasse in der anderen Klasse, zu der eine Verbindung besteht, benutzt wird. Außerdem sind die Unterklassen "Menue", "EingabeFenster" und "AusgabeFenster" der Klasse "BildschirmFenster" der Übersichtlichkeit des Diagramms halber nicht dargestellt und somit entfallen auch die Beziehungen zu ihnen.

Bei den Anwendungsfällen haben sich nur geringere Veränderungen ergeben: auch sie sind durch weitere ergänzt worden, die einfache Dienste, die vorher unberücksichtigt geblieben sind, bereitstellen. Ein Beispiel hierfür ist das Ändern von Kunden-, Lieferanten- oder Produktdaten. Außerdem war es sinnvoll die Anwendungsfälle "Bestellung annehmen" und "Bestellung bearbeiten" zusammenzufassen (s.o.: 1. Allgemeiner Aufbau des Programms).

 

 

4. Probleme bei der genauen Implementierung des ursprünglichen Klassen-Modells 

Im ursprünglichen Modell besaß keine Klasse weder einen Konstruktor, noch einen Destruktor. Zum Teil enthielten die Klassen eine Operation Neu, die ähnliche Aufgaben übernehmen sollte. In diesem Programm hat eine Operation jedoch nur den Namen Neu erhalten, wenn durch ihren Aufruf die Attribute, die nicht vom Programm zugewiesen werden, durch einen Bildschirmdialog eingegeben werden müssen. In allen anderen Fällen, in denen eine Instanz einer Klasse ggf. unter Zuweisung einiger Attribute erzeugt werden soll, wird hierfür immer der Konstruktor verwendet. Es sei darauf hingewiesen, das nur die Klasse Liste einen nicht trivialen Destruktor besitzt.

Aufgrund der geringeren Detaillierung des ursprünglichen Modells besitzen die dort definierten Klassen keinen Operationen zur Abfrage von Attribut-Werten. Bei der Implementation sind solche Operationen jedoch notwendig, da in objektorientierten Ansätzen auf Grund der Datenkapselung sonst normalerweise nicht auf diese Werte zugegriffen werden kann.

Durch die Klasse Verwaltung wurden weitere Probleme bei der Implementierung geschaffen: im ursprünglichen Modell war diese Klasse nicht mächtig genug. Dadurch, daß in ihr alle Klassen zusammenlaufen und deshalb alle aktuellen Instanzen der Objekte verwaltet werden müssen, sind Listen bzw. Karteien für alle zur Laufzeit benötigten Objekte in dieser Klasse erforderlich. Außerdem war es wünschenswert, daß kein Objekt zwei Listen bzw. Karteien gleichzeitig zugeordnet wird. Vor allem die erste dieser beiden Bedingungen war im alten Klassen-Modell nicht erfüllt.

Ein weiteres Problem in diesem Zusammenhang war, daß Objekte einiger Klassen - neben der Klasse Verwaltung - administrative Aufgeben übernehmen sollten. Dieses ist nicht möglich, da eine Instanz einer Klasse nur in sehr geringem Maße auf die Daten anderer Objekte zugreifen kann. Beispielhaft hierfür sei die Operation "kartei_zuordnen" der Klasse Kundenbestellung genannt, die keine Zugriffsmöglichkeiten auf die benötigten Karteien hat.

 

 

5. Implementation der Klassen und ihr Vergleich mit derjenigen des ursprünglichen Modells

Mit Hilfe unten stehender Verweise auf Klassen gelangt man zu der jeweiligen Definition dieser Klasse im Klassen-Modell der Implementation. Daran schließt sich ein Vergleich dieser Klasse zur entsprechenden Klasse des ursprünglichen Modells und Begründungen für Veränderungen an. Damit werden die Veränderungen vom ursprünglichen zum Implemantationsmodell aufgezeigt.

Solange nicht ausdrücklich darauf hingewiesen wird, sind die Klassen dem objektorientierten Prinzip der Datenkapselung unterworfen. Das bedeutet, daß die Attribute einer Klasse als private deklariert sind und auf sie deshalb nur innerhalb der Klasse zugegriffen werden kann. Weiterhin haben alle Klassen, bis auf die Klasse Verwaltung, in der einige Hilfsoperationen als private deklariert sind, ausschließlich Operationen, die public sind.

Die einzigen beiden Klassen, in denen die Attribute als public deklariert werden, sind die Klasse "Bestellung" und die Klasse "Geschäftspartner". Der Grund hierfür ist, daß die aus ihr abgeleiteten Klassen Operationen besitzen, die direkt auf die Attribute der Oberklasse zugreifen sollen. Dieses ist in diesem Konzept nur dann möglich, wenn die Attribute der Oberklasse als public deklariert wurden.

 

Weiter zu den Implementierungen der Klasse:

Die gegebene Reihenfolge ist alphabetisch, bis auf die Hilfsklassen "Liste", "BildschirmFenster" und "Datum", die an den Schluß gestellt wurden.

 

 

6. Beurteilung der UML-Konstrukte

Von sämtlichen von UML zur Verfügung gestellten Diagrammtypen wurden zur Implementation lediglich die Klassenbeschreibungen und die Sequenzdiagramme benutzt (vgl. Sequenzdiagramme des ursprünglichen Entwurfs). Die Klassenbeschreibungen wurden direkt zur Umsetzung der Klassen benötigt. Mit ihrer Hilfe konnten die Klasse bis auf kompliziertere Anwendungsfälle vollständig implementiert werden. Die aufwendigeren Anwendungsfälle konnten dann mit Hilfe der Sequenzdiagramme im Nachhinein implementiert werden.

Die Verwendung eines Diagramms für das Klassenmodell wurde ebenfalls für die Erstellung des Programms nicht benötigt. Ein solches Diagramm ist jedoch dennoch sehr hilfreich, um sich im Nachhinein die Zusammenhänge zwischen den einzelnen Klasse schnell wieder zu verdeutlichen. Dieses ist sehr hilfreich beim Verständnis eines vorliegenden Programmes.

Da Kollaborationsdiagramme die gleichen Inhalte wie Sequenzdiagramme darstellen, bedeuten sie hauptsächlich eine Redundanz, die zur Implementation nicht benötigt wird.

Ähnlich sieht es mit den Aktivitätsdiagrammen aus. Alle in ihnen enthaltenen Informationen sind auch in den Erklärungen der Beziehungen in den Sequenzdiagrammen enthalten. Es währe auch möglich gewesen, sich bei der Implementation auf die Aktivitätsdiagramme zu stützen, jedoch sind nicht beide Diagrammtypen notwendig. Einer der beiden Typen ist ausreichend.

Auch Zustandsdiagramme stellen die Ablaufe der Anwendungsfälle nur aus einer anderen Sichtweise dar und bieten keine neuen und benötigten Informationen. Somit stellen auch sie lediglich eine Redundanz dar.

Um bei größeren Projekten über die Inclusionsahbhängigkeiten zwischen den einzelnen Modulen besser den Überblick zu behalten und damit Fehler abzufangen können Komponentendiagramme hilfreich sein. Jedoch sind auch sie eher ein Hilfsmittel um das Programm nachträglich (wieder) zu verstehen.