Schritt-für-Schritt - Durchführung der Entwurfsphase

Die Entwurfsphase

Nach dem Abschluss der Analyse wissen wir zunächst nur, was genau wir wollen. Wir haben alle uns bekannten Produktfunktionen in einem Pflichtenheft zusammengefasst und sind uns über die Objektstruktur im Klaren, nachdem wir das statische Analyse-Klassendiagramm mit Unterstützung der Sequenzdiagramme bzw. CRC-Karten erstellt haben.
Nochmal: das "was" ist geklärt. Fahren wir also mit dem "wie" fort.

Nun. Dieses Praktikum stellt sicher eine Besonderheit in den Entwicklungsprozessen dar. Nämlich insofern, dass wir ein bereits existierendes Framework wiederverwenden werden. In den ersten Abschnitten des Entwurfes gilt es also, die Ergebnisse der Analyse an das Framework anzupassen. Wir müssen die Konzepte hinter unseren "Datencontainern" erkennen und im Framework wiedererkennen. Dann schauen wir nach den richtigen Vererbungsbeziehungen, um uns zu ersparen, das Rad immer wieder neu zu erfinden (die eigentliche Idee von Frameworks). Wir haben ja schon fast alles im Framework drin. Wir müssen nur aufpassen, dass wir das Framework auch wirklich nur dort einsetzen, wo es sinnvoll erscheint. Nicht jedes assoziative Feld ist auch immer gleich ein Katalog! Spätestens an dieser Stelle sollte sich jeder im Team nochmal intensiv mit dem Framework auseinandersetzen. Nur so kann der Entwurf auch wirklich gelingen.

Anschließend werden wir uns den Produktfunktionen aus dem Pflichtenheft widmen und uns mit Hilfe ihrer Beschreibung und der Sequenzdiagramme daran setzen, Zustandsübergangsdiagramme (sog. "state charts") für die Prozesse zu erstellen (denn jeder Prozess lässt sich ja bekanntlich als ein solches darstellen).
Und bevor wir mit dem Benutzerhandbuch in die zweite Runde gehen können, wird der Entwurf für die Oberfläche erstellt, damit wir uns im Handbuch darauf beziehen können.

Noch eine wichtige Bemerkung bevor es losgeht: sowohl die Java-Dokumentation als auch das Framework (und überhaupt fast alles in der Branche) sind in englischer Sprache abgefasst. Auch wenn es einiges Unbehagen hervorrufen wird, sollte man sich im Entwurf langsam an eine englische Notation (zumindest bei der Namensgebung für die Typen) gewöhnen. Wir werden jedenfalls so verfahren.


Wiederverwendung von SalesPoint

So langsam aber sicher geht es jetzt ans "Eingemachte", denn bei der Durchführung dieser Entwicklungsphase könnt ihr endlich euer mühsam erlerntes Wissen über das SalesPoint Framework einsetzen. Schwierig wird es jedesmal dann werden, wenn die Entscheidung für oder gegen einen spezifischen SalesPoint-Typ zu treffen ist.

Für alle, die nicht mehr wissen, welche grundlegenden Konzepte SalesPoint für uns realisiert, hier noch mal ein kurzer Überblick (eine längere Ausführung findet ihr im Technischen Überblick):

Der aufmerksame Leser wird bemerken, dass es zwischen Code und Diagramm bei der Variablenbezeichnung einige Unterschiede gibt. Diese beruhen einzig und alleine auf kosmetischen Gründen. Variablen, die mit dem Schlüsselwort private versehen werden, sind nach außen nicht sichtbar. Daher wählen die Programmierer aus verschiedenen Gründen hier eine weniger zugängliche Notation. Da diese die Lesbarkeit des Klassendiagramms erschwert wurden diese Namen im Diagramm leicht verändert. Kommen wir jetzt zur Beschreibung des Entwurfs-Klassendiagramms. Im Zuge dessen wird auch immer gleich erwähnt, warum wir uns für oder gegen einen bestimmten SalesPoint-Typ bei der Umsetzung des statischen Klassendiagramms aus der Analyse entschieden haben.



Entwurfs-Klassendiagramm
Abbildung 3.1: Entwurfs-Klassendiagramm


Natürlich wird der SMarket vom Shop abgeleitet. Er ist das zentrale Verwaltungselement der Anwendung, da er für die Speicherung aller möglichen Anwendungsdaten verantwortlich ist. Der Typ Shop ist jeder Klasse der Anwendung bekannt. Um also schnell an die Anwendungsdaten zu kommen, lag die Implementierung des Marktes als Shop auf der Hand.

Die Umsetzung der Benutzerfunktionen als SalesPoint-Prozesse wird erst im übernächsten Kapitel besprochen, weshalb wir jetzt nicht näher darauf eingehen möchten. Dasselbe gilt übrigens auch für die SalesPoints, die in demselben Kapitel besprochen werden.

Unsere Anwendung unterscheidet zunächst zwei Typen von Nutzern. Die Angestellten des Marktes und die Kunden. Zu den Kunden gibt es nichts weiter zu sagen. Dieser Typ wird von UPerson abgeleitet, der wiederum ein User ist. UPerson speichert die Daten, die allen Anwendungsnutzern gleich sind. Die anderen von UPerson abgeleiteten Klassen sind die Mitarbeiter des Marktes. Sie werden im Typ UStaffer zusammengefasst und durch ein Flag in UStaffer unterschieden. An dieser Stelle wäre natürlich auch eine Vererbung möglich.

Im folgenden Kapitel werden wir die Einbeziehung der Kataloge und Bestände näher unter die Lupe nehmen.


Weitere Entwurfsentscheidungen

Wir haben auf die Implementierung eines Typs "Hersteller" verzichtet, weil in Absprache mit dem Betreuer festgelegt wurde, dass die Berechnung der Dauer einer Lieferung nicht mehr herstellerabhängig vorgenommen wird, sondern in dieser Simulation von einem Zufallsgenerator bestimmt wird. Dies vereinfacht die Implementierung ein wenig. In einer späteren Version ließe sich dies natürlich leicht ersetzen.

Auf die Umsetzung einer Klasse für die Buchhaltung haben wir ebenfalls verzichtet, weil deren Funktionen vom Markt übernommen wurden und die Implementierung einer Buchhaltung nicht mehr nötig war.

Es gibt keinen InfoStand mehr. Zum Einen haben wir auf die Umsetzung der Auslage von Werbematerialien verschiedener Hersteller verzichtet und die einzige andere Anwendung des InfoStands, die Verwaltung des Kundenstammes, wurde in den Markt verlagert. Was die Anmeldung von Kunden und die Registrierung neuer Kunden angeht, so wurde diese Funktionalität von einem Prozess übernommen, der das einzige Äquivalent zum InfoStand im Entwurf darstellt.

Die Kassen des Marktes sind ebenfalls nicht als Typ vorgesehen da die Funktion der Bezahlung des Einkaufs des Kunden im Rahmen eines SalesProcess vorgenommen wird und der Bargeldbestand der Kassen innerhalb der Anwendung sofort in den Geldbestand des Marktes übergeht.

Schließlich kommen wir zu den Statistiken. Sie wurden, wie man sich sicher erinnert, auf Grundlage der ausgestellten Kassenzettel und Bestellungen des Marktes erstellt. So war es jedenfalls in der Analyse vorgesehen. Jedoch haben wir uns dazu entschieden, diese Daten als Kataloge zu implementieren. Mehr dazu im nächsten Kapitel.


Konkretisierung: Katalogs- und Bestandsklassen

Kataloge:
In unserer Anwendung haben wie vielfach Listen, die speichern wie oft ein Artikel vorhanden ist. Dies bezeichnet man als Bestand. Da ein Bestand immer einen Katalog benötigt, auf den er sich beziehen kann sind unsere Artikel als Katalog definiert. Der sicherlich wichtigste Katalog sind die Artikel aus dem Angebot der Hersteller bzw. des Marktes. Der Katalog heißt CArticleCatalog und ist von CatalogImpl abgeleitet. Bei den Einträgen des CArticleCatalog, unseren Artikeln, handelt es sich um Objekte des Typs CIArticle, der wiederum eine Ableitung von CatalogItemImpl ist.

Warum die erwarteten Lieferungen einen extra-Katalog (COpenPurchaseOrders) bekommen haben dürfte nicht so offensichtlich sein. Es spricht nämlich zunächst nichts für eine Vererbung der Catalog-Funktionalität des Frameworks. Wir haben uns hier dennoch für einen Catalog entschieden, weil die Lieferungen in der Anwendung übersichtlich in Tabellenform dargestellt werden sollen. Natürlich (wer hätte je daran gezweifelt? :-) ) gibt es auch hier SalesPoint-Klassen, die die Darstellung von Typen des Frameworks in Tabellen sehr stark vereinfachen. Die Umsetzung der Liste der erwarteten Lieferungen als Catalog geschah somit aus Gründen der Bequemlichkeit.

Kommen wir zu den Statistiken. Sie wurden ebenfalls als Kataloge (CSalesStats) umgesetzt und viele werden sich auch hier nach dem 'Warum' fragen. Und ehrlich gesagt gibt es hier keinen triftigen Grund dafür. Erst recht, wo wir doch zu Beginn der Entwurfsphase hervorgehoben haben, das die Verwendung des Frameworks nur stattfinden soll, wo dies auch sinnvoll ist - sprich: wo spezielle Funktionalität der Framework-Typen auch wirklich gebraucht wird. Das ist immer eine gewisse Gradwanderung. An dieser Stelle wären beide Varianten (mit und ohne Salespoint) möglich gewesen. Nach einer kleinen Diskussion haben wir die Speicherung der Statistiken in Katalogen vorgenommen, weil diese über schnelle Suchfunktionen verfügen und die Indizierung der Einträge sehr leicht fällt.

Bestände:
Gehen wir nun auf die Bestände ein und beginnen mit dem Vater aller Bestände des Marktes: dem Angebot. Es wird durch die Klasse CSOffer repräsentiert, was von der Klasse CountingStockImpl abgeleitet ist. Die Einträge dieses Bestands beziehen sich natürlich auf die Artikel aus dem CIArticleCatalog. Zu keinem der Einträge müssen zusätzliche Daten gespeichert werden, weshalb hier ein CountingStock vollkommen ausreichend ist.

Weiter gehts mit CSOrder, einem weiteren CountingStock. Hierbei handelt es sich um den Einkaufskorb des Kunden und seine Einträge sind ebenfalls auf Artikel gerichtet, d.h. sie zählen die Anzahl der Artikel im Einkaufskorb des Kunden. Auch bei diesem Bestand sind Zusatzinformationen, die einen StoringStock nötig machen würden, nicht gewünscht.

Kommen wir zum SICustomer, einer Klasse die von StockItemImpl erbt. Bekanntlich reihen sich die Kunden nach dem Einkauf in der Kassenwarteschlange ein. Eine Instanz dieser Klasse repräsentiert einen solchen wartenden Kunden in der Warteschlange.


SalesPoint-Prozesse als Zustandsdiagramme

Wie bereits im Technischen Überblick erklärt wurde, finden alle Interaktionen von Nutzern mit der Anwendung innerhalb sogenannter Prozesse statt, die immer mit einem SalesPoint verbunden sind (mit Ausnahme der Hintergrund-Prozesse für den Shop). Nach einer Übersicht (Abbildung 2.1) wollen wir im Einzelnen auf jeden Prozess unserer Anwendung eingehen. Zusammen mit einer grafischen Darstellung der Interaktion (für die man am Besten auf Zustandsdiagramme zurückgreift) ist stets eine detaillierte Beschreibung des jeweiligen Prozesses angegeben.



Übersicht: Anwendungsprozesse
Abbildung 3.2: Übersicht: Anwendungsprozesse


Ihr werdet sicherlich vieles hier aus dem Pflichtenheft bzw. unserem Benutzerhandbuch, Version 0.1 wiedererkennen. Ist ja auch klar! Beginnen wir doch endlich mit der Umsetzung unserer Träume aus der Analysephase. :-)

Bekanntlich wird hier eine fensterbasierte Anwendung mit Maussteuerung entworfen. Weil sowieso alles dorthin führt und die Prozesse sich auf diese Weise leichter beschreiben lassen, beziehen sich die meisten erläuternden Texte auf den Oberflächen-Entwurf aus dem nächsten Kapitel.

Anmeldung eines Nutzers

Die Anmeldung eines neuen Nutzers bei der Anwendung beginnt immer mit einer Eingabemaske (im initial gate), wo er sich durch die Eingabe seines Namens und des ihm zugewiesenen Passworts identifizieren muss.



Anmeldung eines Nutzers
Abbildung 3.3: Anmeldung eines Nutzers


Hierbei kann es zu zwei Fehlerfällen kommen: es ist nämlich möglich, dass ein Nutzer, der bereits am System angemeldet ist, versucht, sich ein zweites Mal anzumelden. In diesem Fall geht der Prozess nach dem Drücken des Ok-Buttons in der Anmeldemaske über in das user is logged gate, wo der Nutzer über sein unkorrektes Tun informiert wird und nach nochmaligem Drücken des dort erscheinenden Ok-Buttons zur Anmeldemaske zurückgelangt. Der zweite Fehler, den ein Nutzer machen kann, ist eine gänzlich falsche Anmeldung. Das betrifft zum Einen den Fall eines eingegebenen Nutzernamens, den das System nicht kennt, und zum Anderen ein falsches Nutzerpasswort. Auch hier springt der Prozess zu einem gate mit einer Fehlermeldung, dem log on failed gate.

Natürlich hat der Nutzer jederzeit die Möglichkeit, innerhalb der Anmeldemaske einen Abbruch der Anmeldung durch Drücken des Cancel-Buttons herbeizuführen.

Und jetzt wirds kompliziert! Wie man in der Abbildung sehen kann, wurden die weiteren Aktionen, die durch eine korrekte Anmeldung gestartet werden, als nebenläufige Prozesse in das Diagramm eingezeichnet. Das liegt ganz einfach daran, dass der eigentliche Prozess der Anmeldung mit dem Starten des jeweils anderen Prozesses ruht und erst terminiert, wenn dieser beendet wurde.

Für jeden der Akteure (Actor), den es in unserer Simulationsanwendung gibt, wurde ein (mehr oder weniger) komplexer Prozess geschrieben, der alle Aktionen, die dem jeweiligen Nutzer zur Verfügung stehen, bereitstellt. Sie werden im Laufe dieses Kapitels vorgestellt.

Registrierung neuer Kunden

Zur Eingabe der zahlreichen Kundendaten wird dem Nutzer zu Beginn dieses Prozesses am initial gate eine übersichtliche Eingabemaske angezeigt. Den Abschluss der Eingabe macht der neue Kunde mit der Betätigung des Ok-Buttons unter dem Formular, der zunächst eine Aktion hervorruft, die die Eingaben (insbesondere das Passwort) prüft. Ein falsches Passwort führt den Nutzer zum password failed gate, das ihn mit einer Fehlermeldung straft und das er durch nochmaliges Drücken des Ok-Buttons für eine Korrektur seiner Eingaben wieder verlassen kann.



Registrierung neuer Kunden
Abbildung 3.4: Registrierung neuer Kunden


Ähnlich wird auch mit anderen falschen Eingaben verfahren. Sie werden durch eine Fehlermeldung in einem Meldungsfenster angezeigt und nicht in einem eigens dafür geschriebenen gate dargestellt. Will der Nutzer nach so vielen Fehlermeldungen entnervt aufgeben, kann er das mit Hilfe des Zurück-Buttons unter dem Eingabeformular gerne tun. Es beendet den Prozess mit einer Umleitung über das stop gate.

Ist die Anwendung irgendwann mit wirklich allen Eingaben des neuen Kunden einverstanden, geht der Prozess im confirmation gate weiter, wo der Kunde um eine nochmalige Bestätigung seiner Eingaben gebeten wird. Eine Betätigung des Zurück-Buttons an dieser Stelle führt ihn wieder zurück zum initial gate mit dem Eingabeformular. Ein Drücken des Ok-Buttons jedoch beendet die Registrierung mit der Speicherung der neuen Kundendaten.

Einkauf des Kunden

Jetzt wollen wir mit den Funktionen des Kunden beginnen. Sie geben schließlich den Ausschlag für alles weitere in der Anwendung, d.h. andere Aktionen von Kassierern und Lagerarbeitern basieren immer auf dem Einkauf eines Kunden.



Einkauf des Kunden
Abbildung 3.5: Einkauf des Kunden


Nach der Anmeldung bei der Anwendung stellt ein initial gate die Anzeige seines PDA's dar, die sich aus dem aktuellen Angebot des Marktes mit einer kurzen Beschreibung eines jeden Artikels und dem Inhalt seines Einkaufskorbes zusammensetzt. Mal abgesehen davon, dass er sich jederzeit beim System abmelden kann, was einen Übergang (Transition) zum stop gate von SalesPoint und die Beendigung des Prozesses zur Folge hat, wird er jetzt sicherlich seinen Einkaufskorb reichlich füllen.

Was immer er auch in den Einkaufskorb legt, eine Betätigung des Zurück-Buttons auf seinem PDA-Bildschirm hat fast dasselbe zur Folge, wie die Abmeldung. Der Inhalt seines Einkaufskorbes geht sofort wieder in den Bestand des Marktes über (was durch den Umweg über das rollback gate beinahe automatisch geschieht) und der Kunde begibt sich zurück auf seinen Start-SalesPoint (bisher als der InfoStand bekannt).

Natürlich verfügt die Anzeige seines PDA's auch über einen Kaufen-Button, der (im Falle, dass überhaupt etwas im Einkaufskorb liegt) den Prozess zum affirmation gate führt, wo dem Kunden eine Zusammenfassung seines Einkaufs inklusive der zu erwartenden Kosten angezeigt wird. Nach nochmaligem Drücken auf einen Kaufen-Button gelangt er zum ok gate, das den Kunden zum Gang zur nächstgelegenen Kasse auffordert, wo er sich schließlich in die Warteschlange einreiht.

Die Kassenbedienung

Vor der Kasse bildet sich mit der Zeit eine (hoffentlich nicht zu lange) Warteschlange, die dem Kassenbediener nach der Anmeldung bei der Anwendung angezeigt wird. Daraus kann er sich nun einen Kunden auswählen, dessen Einkauf er nun abrechnen oder stornieren will. Diese zwei Aktionen werden durch entsprechend benannte Buttons ausgelöst, die ziemlich empfindlich reagieren, wenn zuvor kein Kunde ausgewählt wurde. Sie leiten dann den Kassierer zum no customer gate, dass ihn mehr oder weniger freundlich dazu auffordert, doch bitte einen Kunden für die Aktion zu bestimmen.



Die Kassenbedienung
Abbildung 3.6: Die Kassenbedienung


Die Stornierung des Einkaufs eines Kunden findet im cancel buy gate statt, wo der Kassierer nochmals zur Bestätigung für das Löschen des Kunden aus der Warteschlange aufgefordert wird. Dies kann er durch Drücken des Ok-Buttons tun oder er überlegt es sich nochmal anders und drückt stattdessen den Zurück-Button. Dann passiert nichts weiter und er findet sich im initial gate mit der Übersicht der Kassenwarteschlange wieder.

Kunden werden am order gate bedient, das dem Kassierer den Inhalt des Einkaufskorbes als Kassenzettel zusammengefasst anzeigt und ihm einen Rabatt für den Kunden vorschlägt. Er kann jetzt die Zahlungsart wählen (zwischen Barzahlung und der Zahlung mit Kreditkarte) und den vorgegebenen Wert für den Rabatt anpassen. Natürlich steht es ihm auch frei, die Abfertigung dieses Kunden abzubrechen indem er den Zurück-Button betätigt.

Ein Drücken des Buttons mit der Aufschrift Zahlung beendet schließlich den Vorgang an der Kasse und der Kunde kann (nach einiger Wartezeit) die Artikel von einem der Lagerarbeiter in Empfang nehmen. Das von ihm bezahlte Geld landet sofort im Bestand des Marktes und steht fortan dem Manager für seine Einkäufe und Lohnzahlungen zur Verfügung.

Lagerarbeiten

Nachdem der Kunde die Bezahlung an der Kasse beendet hat, werden die Daten seines Einkaufs an das Lager weitergereicht. Die Abarbeitung der Lieferungen dort findet nach dem FIFO-Prinzip (first in, first out) statt. Ein angemeldeter Lagerarbeiter hat deshalb keine Übersicht über die wartenden Kunden sondern nur die Angabe über ihre Anzahl in seinem initial gate. Ist sie größer als 0 und der Lagerarbeiter entscheidet sich für die Zusammenstellung der nächsten Lieferung, wird der Prozess im order gate mit einer übersichtlichen Darstellung der zu liefernden Artikel fortgesetzt.



Lagerarbeiten
Abbildung 3.7: Lagerarbeiten


Hier kann der Arbeiter zwischen drei Aktionen wählen. In den meisten Fällen wird er jetzt die Waren zusammensuchen und einen Eintrag nach dem anderen in der Liste abhaken. Stellt er dabei einen Fehlbestand fest, muss er diesen natürlich sofort melden. Dies geschieht durch Eingabe der tatsächlich vorhandenen Menge des Artikels im edit gate. Für diese Eingabe sollte ein Eintrag aus der Artikelliste ausgewählt sein, denn sonst führt das zu einer Fehlermeldung, die im no item selected gate angezeigt wird. Eine Korrektur des Bestands verlangt von ihm noch eine Bestätigung im edit confirmation gate ab.

Sind alle Artikel geliefert worden (in der Liste abgehakt), kann der Lagerarbeiter den Auftrag endlich als abgeschlossen deklarieren indem er den entsprechenden Button dafür im order gate drückt. Irrt er sich und es existieren noch offene Posten in der Liste, wird er durch eine Fehlermeldung im not ready gate darauf aufmerksam gemacht und kann anschließend durch Drücken auf den Ok-Button der Fehlermeldung seine Missetat korrigieren.

Ist jedoch alles in Ordnung, führt ein Klick auf den Button für den Auftragsabschluss zum commit gate, das eine Protokollierung der Aktivität zur Folge hat und den Prozess schließlich zum initial gate führt.

Das Marktmanagement

Leider sahen wir uns gezwungen, dass gesamte Management des Marktes in einen einzigen Prozess zu pressen. Die Gründe dafür spielen jetzt keine Rolle. Jedenfalls ist der Prozess an sich viel zu komplex um ihn(immer noch übersichtlich) in einem einzigen Diagramm darzustellen. Aus diesem Grunde haben wir ihn für die Dokumentation in mehrere Diagramme zerlegt und erklären nun jedes einzelne für sich.



Öffnen & Schließen
Abbildung 3.8: Öffnen & Schließen


Der Markt kennt zunächst zwei wichtige Zustände. Er ist für Kundeneinkäufe geöffnet oder geschlossen. Einige Aufgaben des Managements (beispielsweise Preisänderungen im Angebot) lassen sich nur im geschlossenen Zustand erledigen um den reibungslosen Kundenbetrieb (etwa wegen Tumulten aufgrund prompter Preisanstiege) nicht zu gefährden.

Einiges ist völlig klar: ist der Markt geöffnet, kann man ihn schließen. Umgekehrt geht das genauso. Beides ist für den Manager im open close gate seines Prozesses möglich. Für das Schließen gibt es allerdings eine Bedingung: es darf sich zum gegebenen Zeitpunkt kein Kunde oder anderer Mitarbeiter außer dem Manager im Markt aufhalten. Sollte es der Chef dennoch versuchen, wird er durch eine Fehlermeldung in einem Meldungsfenster (kein gate!) darüber informiert, dass es so nicht geht.

Ein schönes feature stellt die Ankündigung des Feierabends dar. In dem Fall (Betätigung des entsprechenden Buttons) wird eine Nachricht an alle angemeldeten Nutzer gesendet, die sie darüber informiert, dass der Markt in Kürze schließen wird. Ein angekündigter Feierabend lässt sich auch wieder zurücknehmen.



Warenbestand
Abbildung 3.9: Warenbestand


Die Anzeige des aktuellen Warenbestands des Marktes könnte man durchaus als das default-gate des Managers bezeichnen. Sie wird sofort nach seiner Anmeldung im stock main gate angezeigt. Das initial gate des Manager-Prozesses hat keine weitere Funktion, als auf den Warenbestand zu verweisen.



Wareneinkauf
Abbildung 3.10: Wareneinkauf


Der Einkauf neuer Waren für den Markt durch den Manager läuft ganz ähnlich wie der Einkauf des Kunden ab. Er wählt aus einer übersichtlichen Darstellung des Warenkatalogs im purchase main gate die Waren aus, für die er sich interessiert und legt die Anzahl der zu liefernden Exemplare fest. Entscheidet er sich für den Kauf (durch Klick auf den entsprechenden Button), wird ihm im purchase confirmation gate eine Zusammenfassung mit dem zu zahlenden Preis angezeigt und eine Bestätigung der Bestellung erbeten. Durch Betätigung des Zurück-Buttons kann er noch einmal zur Einkaufsliste zurückgehen und diese ändern. Ein Abbruch im purchase confirmation gate löscht die Einkaufsliste und führt den Manager ebenfalls zur Übersicht zurück. Nur durch Drücken des Bestätigen-Buttons wird der Einkauf wirklich durchgeführt, die Bestellung an die jeweiligen Hersteller abgeschickt und natürlich das Geld vom Marktkonto an die Hersteller überwiesen. Die Lieferung erfolgt dann (abhängig von der Entfernung des Herstellers zum Markt) nach ein paar Tagen.



Lieferungen
Abbildung 3.11: Lieferungen


Besagte Lieferungen werden dauerhaft gespeichert und können in einem anderen Teil des Manager-Prozesses abgerufen werden. Eine Übersicht über die im Moment erwarteten Lieferungen bekommt man im opo main gate. Nach der Auswahl eines der Einträge aus dieser Liste kann sich der Manager dann auch noch die Details im opo details gate anschauen von wo aus er durch Betätigung des Zurück-Buttons wieder in die Übersicht zurück gelangt.



Angestellte
Abbildung 3.12: Angestellte


Im empl edit main gate wird dem Manager eine Liste aller gegenwärtig im Markt angestellten Mitarbeiter angezeigt. Hier stehen ihm dann 3 weitere Aktionen zur Verfügung:

Eine Änderung der Mitarbeiterdaten kann er in der Detailansicht eines ausgewählten Angestellten im empl edit detail gate vornehmen. Hier werden ihm zunächst die Details der Mitarbeiterdaten als default-Einstellungen einer Eingabemaske dargestellt und es steht ihm natürlich (in seiner Eigenschaft als El Chefe) völlig frei nach Belieben darin herumzuschreiben. Übernommen werden die Daten erst nach Betätigung des Ok-Buttons, der zuvor die Daten auf Vollständigkeit und Korrektheit prüft und den Manager über etwaige Fehler informiert. Mit dem ebenfalls im Eingabeformular integrierten Zurück-Button gelangt der Manager in die Übersicht zurück. Die Eingaben werden dann verworfen.

Aktion No.2 ist die Einstellung neuer Mitarbeiter. Sie wird ebenfalls im empl edit detail gate vorgenommen nur das in diesem Fall die Eingabemaske vollkommen leer ist. Die Funktionen ähneln der Maske für die Mitarbeiterdetails. Lediglich der Ok-Button weicht etwas davon ab, da er diesmal einen gänzlich neuen Mitarbeiter in die Firma aufnimmt und nicht die Daten eines bestehenden Angestellten ändert.

Drückt der Manager im empl edit main gate den Button für die Entlassung eines (zuvor in der Liste markierten) Mitarbeiters, wird er in einem Meldungsfenster um eine Bestätigung seines Vorhabens gebeten. Tut er das, wird der Mitarbeiter aus der Firma entlassen und ihm wird ein Entlassungsgeld ausgezahlt, das auf der Dauer seiner Beschäftigung und dem zuletzt gezahlten Gehalt basiert.



Kundenstamm
Abbildung 3.13: Kundenstamm


Eine übersichtliche Darstellung des Kundenstammes der Firma erhält der Manager im cust edit main gate. Nach der Auswahl eines Eintrags aus dieser Liste kann er sich die Details zum Kunden im cust edit details gate anschauen und einige wenige davon (Passwort und die Höhe des Treuerabatts) ändern. Diese Detailansicht eines Kunden enthält neben dem Zurück-Button, mit dem der Manager in die Übersicht zurückgelangt, auch noch über einen Button zur Anzeige der Kundenstatistik (bisherige Einkäufe) im customer stats detail gate. Von dort aus kommt er mit Hilfe des Buttons mit der Aufschrift Kundendaten zurück zur Detailansicht des Kunden selbst.

Schließlich steht dem Manager im cust edit main gate noch eine Funktion zur Beendigung der Geschäftsbeziehung zum Kunden zur Verfügung. Da das für den Kunden durchaus von einiger Bedeutung ist (Verlust des bisher erwirtschafteten Rabatts) wird der Manager nochmal um eine Bestätigung in einem Meldungsfenster (kein extra gate) gebeten. Der Kunde wird nur dann aus dem Kundenstamm gestrichen, wenn der Manager auch die noch bejaht.



Statistiken
Abbildung 3.14: Statistiken


Die Erstellung der Statistik für die Artikel beginnt im article stats main gate, wo der Manager aus einer Liste von Artikel auswählen und den Zeitraum für die Statistik festlegen kann. Zur besseren Übersicht existiert hier auch noch eine Box zum Filtern der Artikel einer bestimmten Produktkategorie. Eine Auswahl aus der Kategorieliste aktualisiert sofort die Ansicht. Hat der Manager einen Artikel ausgewählt und klickt auf den Detail-Button wird ihm schließlich ein Einblick in die Verkaufsstatistik des von ihm ausgewählten Artikels für den bestimmten Zeitraum im article stats detail gate gewährt. Dieses gate kann er durch Betätigung des Zurück-Buttons wieder verlassen und zur Artikelübersicht zurückkehren.

Eine Umsatzstatistik bekommt der Manager im overall stats gate präsentiert. Auch hier kann er den Zeitraum variieren, was eine sofortige Aktualisierung der Anzeige hervorruft.
Das customer stats main gate wurde bereits bei der Verwaltung des Kundenstammes besprochen.



Einstellungen
Abbildung 3.15: Einstellungen


Abschließend bleibt uns nur noch das options gate. Es dient diversen Einstellungen für die Aktivitäten am Markt und stellt die aktuellen Einstellungen beim Laden als default-Werte für neue Einstellungen dar. Mit der Betätigung des Übernehmen-Buttons kann der Manager die von ihm eingegebenen Werte speichern. Vorher prüft jedoch das Programm diese eingehend und gibt dem Manager in einem Meldungsfenster Auskunft darüber, wenn es mit den neuen Einstellungen nicht klarkommt. Ansonsten übernimmt es sie anstandslos und speichert sie ab.


Oberflächen-Entwurf

Allgemeines zum Oberflächen-Entwurf

Für die Erstellung des Oberflächen-Entwurfs gibt es viele verschiedene Möglichkeiten und eurem Erfindungsreichtum sind hier überhaupt keine Grenzen gesetzt.
Dabei könnt ihr verschiedentlich detailliert vorgehen. Die Palette reicht von ein paar beschriebenen Screenshots bis zum voll funktionsfähigen interaktiven Programm.

Eine Möglichkeit ist, die Benutzeroberflächen per Hand und Stift in Papierform zu entwickeln und anschließend die Entwürfe einzuscannen. Die Bilder werden dann im Dokument mit Hilfe von Kommentaren beschrieben. Wer mit der Maus besser umgehen kann als mit dem Stift darf natürlich auch gerne ein Grafikprogramm verwenden.
Ähnlich geht es auch mit zahlreichen Entwicklungswerkzeugen, die einen eingebauten GUI-Editor besitzen. In den bisher stattgefundenen Praktika kamen dabei u.a. der

zum Einsatz.
Dabei enthalten auch die Nicht-Java-Editoren größtenteils Oberflächen-Elemente, die auch in Java Verwendung finden. Sie müssen sich schließlich auch an die Fenster-Gestaltungs-Regelwerke halten.

Noch ein Tipp: für die ganz abgehobenen Entwicklerteams möchte ich persönlich die Skriptsprache Python empfehlen. Sie wurde zunächst einzig und allein für den Zweck entworfen, schnell Entwürfe für Benutzeroberflächen zu schreiben, die anschließend sogar spielbar sind!
Auch wenn es diese Alternative gibt, wird sie für das Bestehen des Praktikums nicht gefordert, da sich die Entwicklungsdauer für Python-unerfahrene Gruppen unnötig in die Länge ziehen würde.

Auf die Java-IDE's möchte ich besonders eingehen, da es hier ganz tolle Möglichkeiten gibt, die erstellten Oberflächen später in der Anwendung tatsächlich wiederzuverwenden. Sie müssen nur geringfügig umgeschrieben und nicht komplett neu im Quellcode entwickelt werden. Das kann die Dauer der Implementierungsphase erheblich verkürzen, hat aber ein gravierendes Manko: diese Editoren haben keinen blassen Schimmer von SalesPoint und verwenden nur Elemente aus Swing bzw. AWT. Deshalb stehen euch, solltet ihr euch zu diesem Schritt entscheiden, nicht die herausragenden Vereinfachungen einer SalesPoint-only Oberfläche zur Verfügung. Auch solltet ihr euch auf gar keinen Fall dazu verleiten lassen mit eurem Oberflächen-Entwurf in der Implementierung weiterzuarbeiten. Daher raten wir hier von einer intensiven Verwendung der Java-IDE zum Oberflächen-Entwurf eher ab. Um euch mit der Oberflächenprogrammierung näher zu befassen gibt es den Prototypen im nächsten Kapitel.

Sind die Screenshots der Oberfläche erstellt, kommt man zum nächsten Schritt: der Beschreibung. Sie sollte zum Einen den Inhalt des Fensters erklären und zum Anderen die Funktionen seiner Oberflächen-Elemente erläutern. Dabei kommt es (ganz besonders bei den SalesPoint-Prozessen, deren Teil diese Oberflächen nun einmal sind) zu Abfolgen von Fenstern, die miteinander durch Betätigung von Buttons o.ä. verknüpft sind. Hier ist, ähnlich wie in den Zustandsübergangsdiagrammen im vorigen Kapitel, auf die Bedingungen für den Übergang von einem Fenster ins andere einzugehen. Eine übersichtliche Darstellungsmöglichkeit der Verknüpfungen kann durch beschriftete Pfeile vom Steuerelement zum dadurch ausgelösten Fenster erfolgen.

Dazu erstmal genug. Kommen wir jetzt zum Oberflächen-Entwurf des Großhandels.

Der Oberflächen-Entwurf

Die Beschreibung des Entwurfs der Anwendungsoberfläche führen wir durch, indem wir den gesamten Prozess (nicht mit den SaleProcesses verwechseln!) des Einkaufs - vom Füllen des Einkaufskorbes bis hin zur Auslieferung durch die Lagerarbeiter - anhand der Screenshots beschreiben. Die Dialoge, die auf den Screenshots zu sehen sind, wurden mit Hilfe der JBuilder-IDE entwickelt.

In der folgenden Abbildung ist die Übersicht des Marktangebots und der Inhalt des Einkaufskorbes zu sehen. Der Kunde wählt aus der linken Spalte die Artikel aus, die er kaufen will, gibt im Eingabefeld zwischen den Tabellen die gewünschte Anzahl ein und drückt den Button '>>' um die Artikel in den Einkaufskorb zu legen. Die Anzahl im Einkaufskorb wird daraufhin aktualisiert. Den gegenteiligen Effekt hat eine Betätigung des Buttons mit der Aufschrift '<<'. Damit kann ein zuvor im Einkaufskorb ausgewählter Artikel in die Regale des Marktes zurückgelegt werden. Auch hier ist die Anzahl im Eingabefeld in der Mitte ausschlaggebend. Unter den beiden Tabellen befindet sich eine Textbox, die immer eine Beschreibung des aktuell ausgewählten Artikels aus einer der beiden Tabellen enthält.



Einkaufskorb & Marktangebot
Abbildung 3.16: Einkaufskorb & Marktangebot


Durch die Betätigung des 'Kaufen'-Buttons gelangt man zum folgenden Fenster. Hier wird eine kurze Zusammenfassung des Einkaufs angezeigt. Drückt der Kunde hier den 'Ok'-Button, gilt der Einkauf als beendet und der Kunde reiht sich in die Warteschlange an den Kassen ein.



Einkaufsübersicht
Abbildung 3.17: Einkaufsübersicht

Hier beginnt die Tätigkeit des Kassierers. Er beginnt an einer Übersicht der Kundenwarteschlange an den Kassen, die in der folgenden Grafik dargestellt wird. Nach der Auswahl eines Listeneintrags (also eines wartenden Kunden) kann er dessen Einkauf stornieren oder den Kunden bedienen.



Kundenwarteschlange
Abbildung 3.18: Kundenwarteschlange


Die Abrechnung beginnt mit einer Übersicht des Einkaufskorbes des Kunden. Mal abgesehen davon, das der Kassierer zur Übersicht zurückgehen kann, was einem 'Verweis' des Kunden in die Warteschlange gleichkommt, kann er natürlich den Inhalt des Einkaufskorbes abrechnen.



Inhalt des Einkaufskorbes
Abbildung 3.19: Inhalt des Einkaufskorbes


Damit gelangt er zum Fenster, das in der folgenden Grafik dargestellt wird. Auf die Einkaufssumme wird der Treuerabatt, den der Markt dem Kunden gewährt, angerechnet bzw. abgezogen. Dieser Rabatt kann nachträglich vom Kassierer geändert werden, was eine sofortige Aktualisierung des Rechnungsbetrages zur Folge hat. Weiterhin wird hier die Zahlungsart festgelegt. Bei Zahlung in Bar wird der vom Kunden gezahlte Betrag eingegeben und das Rückgeld berechnet. Ein Drücken des 'Zahlung'-Buttons beendet den Zahlungsvorgang. Bei Barzahlung wird dem Kunden das Rückgeld ausgezahlt. In jedem Fall wird der Rechnungsbetrag auf das Konto des Marktes eingezahlt.



Abrechnung
Abbildung 3.20: Abrechnung


Von nun an übernehmen die Lagerarbeiter die Weiterbearbeitung des Kundeneinkaufs. Ein Lagerarbeiter beginnt im folgenden Fenster mit einer Anzeige der Anzahl der 'wartenden' Lieferungen. Lagerarbeiter haben nicht das Privileg, sich einen bestimmten Kunden auswählen zu dürfen, wie es die Kassierer können. Er beginnt mit dem Kunden, der am längsten wartet und die Bedienung wird durch ein Drücken des Buttons mit der Aufschrift 'Lieferung zusammenstellen' eingeleitet.



Offene Lieferungen
Abbildung 3.21: Offene Lieferungen


Auch der Lagerarbeiter bekommt den Inhalt des Einkaufskorbes des Kunden angezeigt. Alle Artikel, die er im Lager finden konnte und zur Lieferung gepackt hat, werden als "erledigt" abgehakt. Ist die Lieferung komplett (alle Artikel sind als "erledigt" abgehakt worden), kann er den Lieferauftrag als "abgeschlossen" deklarieren indem er den entsprechenden Button auf der Unterseite des Fensters drückt. Die Meldung von Fehlbeständen erfolgt, indem der Lagerarbeiter den betreffenden Artikel aus der Liste auswählt und den 'Fehlbestand' betätigt.



Lieferung zusammenstellen
Abbildung 3.22: Lieferung zusammenstellen


Im daraufhin angezeigten Fenster wird der Name des Artikels und die vermutete Anzahl der vorhandenen Exemplare angezeigt. Aufgabe des Lagerarbeiters ist es jetzt, die tatsächliche Anzahl im Eingabefeld einzutragen und den 'Ok'-Button zu drücken.



Fehlbestandsmeldung
Abbildung 3.23: Fehlbestandsmeldung

Der Prototyp

"Redo until Right" ist das Motto des Prototyping. (laut Balzert, Lehrbuch der Softwaretechnik II 3.3.3)

Nachdem wir unseren Entwurf in Diagramme gepresst haben, und wir uns mit Salespoint bis jetzt eher auf einem theoretischen Niveau bewegt haben, soll in dieser Phase ein Prototyp des Programmes entstehen.
Er soll dazu dienen die Salespoint-Konzepte in die Praxis umzusetzen ohne gleich von der Komplexität des Entwurfs erschlagen zu werden. Wenn man sich das Entwurfsklassendiagramm einmal in Gänze anschaut, weiß man nicht so wirklich an welcher Stelle man denn mit der Implementierung anfangen soll, eine gewisse Angst davor stellt sich ein. Um das zu verhindern gehen wir langsam an die Salespoint-Problematik heran.
Wir werden ein kleines Beispielprogramm entwickeln, dass die Angst vor Salespoint und der Komplexität des Programmes nehmen soll. Zudem zeigt es vielleicht schon während der Entwurfsphase, dass nicht alles so funktionieren kann wie wir uns das gedacht haben. Besser den Fehler jetzt zu entdecken und zu beheben, als erst in der Implementierungsphase. Das erspart einiges an Kopfzerbrechen.
In der Prototyping-Phase könnt ihr noch einmal alle Coding-Standards und Kommentare über Bord schmeißen (auch wenn ihr sie natürlich auch schon einsetzen könnt). Ihr müsst keine Abhängigkeiten zwischen den einzelnen Modulen beachten und nicht unbedingt über Entwurfsmuster nachdenken. Grund dafür ist, dass ihr den Prototyp nach dem Ende des Entwurfs wegwerfen werdet (also nur im übertragenen Sinne) bzw. wird er später nur noch zum Ausprobieren neuer Features verwendet. Er soll also auf gar keinen Fall Grundlage für das fertige Projekt werden. Mit dem Wissen, wie der Prototyp funktioniert, könnt ihr dann bei der eigentlichen Implementierung gelassener und mit mehr Vorwissen an die Sache herangehen. An einem kleinen Prototyp kann man schneller mal eine Sache ausprobieren (auch in verschiedenen Varianten) als an einem größeren und unflexibleren Projekt. Und die Teamkollegen werden nicht erfreut sein wenn das Programm nicht mehr läuft, nur weil ihr ein neues super-duper-Feature testen wolltet. Das ganze an einem Prototypen auszuprobieren ist dagegen überhaupt kein Problem.

Was sollte der Prototyp alles können und wie gehen wir an die Sache heran?
Es gibt kein wirkliches Maß, wie umfangreich so ein Prototyp sein muss. Auch hier hilft wieder ein klärendes Gespräch mit dem Tutor. Der Prototyp sollte natürlich einen Shop beinhalten. Dazu sollte man vielleicht einen Salespoint und einen Prozess einbinden. Ob ihr die Gelegenheit gleich nutzt und euch mit dem Erstellen von Katalogen, Beständen, Formsheets, Tabellen usw. auseinandersetzt, bleibt vollkommen euch überlassen.
Natürlich kann sich der Prototyp auch schon mit eurem fachlichen Thema befassen. Aber haltet dies wenn möglich auf ein Mindestmaß begrenzt. Sonst ist die Versuchung sehr groß, Teile des Prototypen dann auch wieder im fertigen Programm zu benutzen.

Die Herangehensweise ist nicht ganz einfach, da sich so ein Prototyp schwierig auf mehrere Teammitglieder aufteilen lässt. Jedoch soll sich jeder intensiv mit Salespoint beschäftigen, damit dann beim Implementieren keine allzugroßen Wissenunterschiede zu Tage kommen.
Dazu muss jeder im Team einen eigenen Prototyp entwickelt. Sie sollen nicht alle die gleiche Funktionalität erfüllen, die Basisfunktionalität sollte aber in allen gegeben sein.

"Wie fange ich an?" ist sicher die nächste Frage. In allen anderen Kapiteln dieses Tutorials gibt es immer wieder Code-Beispiele, die einem das Nachvollziehen erleichtern. Da der Prototyp aber keine allzu komplexen Themen schneidet und durch den Videoautomaten ein einfaches Tutorial bereits vorhanden ist, gibt es zum Prototypen keinen Beispielcode. Durch reines Copy&Paste versteht man vielleicht viele der Probleme nur halb so gut, daher seid ihr hier ein wenig auf euch selbst angewiesen. Das soll nicht heißen, dass wir euch damit völlig alleine lassen. Das Videoautomat-Beispiel und natürlich auch das Forum bieten mehrere Anlaufstellen, um die ersten Schritte zu erleichtern. Und nicht zuletzt habt ihr einen Tutor, der bei schwerwiegenden Problemen sicher auch zu einer kleineren Einführung bereit ist, wenn ihr ihn/sie nett darum bittet.

So könnte der Prototyp dann z.B. in einer sehr einfachen Form aussehen:



Prototyp-Screenshot
Abbildung 3.24: Prototyp-Screenshot

Das Benutzerhandbuch geht in die 2.Runde

Bisher bestand die Aufgabe unseres Benutzerhandbuchs darin, die Entwickler bei der Analyse der Anwendung zu unterstützen. In dieser Phase der Entwicklung ändert sich jedoch der Adressat des Handbuchs von den Mitgliedern der Entwicklungsabteilung hin zum Endbenutzer der Anwendung, unserem Kunden. Deshalb muss jetzt die Handhabung und das Verhalten der Anwendung vollständig und fehlerfrei beschrieben werden. Sie (die Anwendung) muss ausschließlich unter Zuhilfenahme des Handbuchs bedienbar sein.

Bei der Formulierung des Inhalts ist nun darauf zu achten, dass es sich bei den Endbenutzern der Anwendung größtenteils um EDV-unkundige Benutzer handeln wird und die Inhalte des Handbuchs somit sachlich aber dennoch einfach zu formulieren sind.

Wir haben uns also hingesetzt und das Handbuch für unseren Großmarkt aus Kundensicht verfasst.


previous Analyse der AufgabenstellungImplementierung und Test next



by Thomas Ryssel