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):
- eine zentrale Verwaltungseinheit für die Anwendung, der spätere Shop,
- die verschiedenen Punkte der Interaktion zwischen der Anwendung und dem Benutzer, die SalesPoints,
- die eigentlichen Aktionen, die die Nutzer im Shop durchführen,
- natürlich die Nutzertypen selbst, die die Anwendung kennen muss, um sie bei der Anmeldung identifizieren zu können, also die User,
- schließlich die Kataloge, die das Angebot darstellen bzw. als Verwaltungseinheiten für die Buchführung dienen können und
- die Bestände an Katalogeinträgen, die von der Anwendung verwaltet werden.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
- QT-Designer,
- die Borland-Delphi Entwicklungsumgebung,
- die Java-IDE's von Sun und Inprise (früher unter dem Namen Borland bekannt) und sogar
- der GUI-Editor von MS Access
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
Analyse der Aufgabenstellung | Implementierung und Test |