Bevor im nächsten Kapitel der Ausleihvorgang beschrieben wird, soll eine automateninterne Zeitrechnung implementiert werden, die es gestattet zeitliche Abläufe zu simulieren.
Definition eines Timers
Beim Verleih einer Videokassette muss die Ausleihzeit abgespeichert werden, um beim Rückgabevorgang eine korrekte Abrechnung zu ermöglichen. Natürlich ließe sich dabei auf die Systemzeit zurückgreifen, jedoch wäre es in dieser Simulation wünschenswert, wenn im Zuge des Testens nicht jedesmal die Systemuhr umgestellt werden muss, wenn man ein paar Tage überspringen will.
Glücklicherweise bietet das Framework auch hierfür ein vorgefertigtes Konstrukt. So existieren zwei Interfaces Time
und Timer
, welche eine abstrakte Lösung für die Zeitverwaltung bieten. Dabei stellt Timer
eine Art Zeitmanager und Time
die Zeit selbst dar. Eine Implementation des Zeitmanagers ist StepTimer
, eine Klasse für die Zeit CalendarTime
. Diese beiden Klassen sollen im Videoautomat zur Anwendung kommen.
Wird innerhalb der Anwendung die aktuelle Zeit benötigt, oder ein Objekt muss auf gewisse Zeitereignisse reagieren, so kommt grundsätzlich nur der Zeitmanager zum tragen. Dennoch wird ein Time
-Objekt für die Konstruktion des Zeitmanagers benötigt. Das Zeitobjekt wird quasi im Zeitmanager verwaltet. Die meisten Anfragen an den Manager, z.B. die Frage nach dem aktuellen Datum, werden an das Zeitobjekt delegiert. Darüberhinaus bietet der Manager jedoch zusätzliche Funktionalitäten wie beispielsweise das Informieren über gewisse Zeitereignisse.
Die Initialisierung von StepTimer
wird innerhalb des Konstruktors von VideoShop
vorgenommen und über die Methode setTimer(Timer t)
wird die neue Instanz zum globalen Zeitmanager erhoben.
public class VideoShop extends Shop { . . . public VideoShop() { . . . setTimer(new StepTimer(new CalendarTime(System.currentTimeMillis()))); } . . . }
Dem Konstruktor von CalendarTime
muss ein long
-Wert übergeben werden, der die initiale Zeit repräsentiert. Hier wird die Systemzeit zur Initialisierung genutzt. Der Aufruf System.currentTimeMillis()
liefert einen long
-Wert, der die Anzahl der vergangenen Millisekunden seit dem 1.Januar 1970 0:00 Uhr GMT bis zum jetzigen Zeitpunkt repräsentiert.
Die Zeit weiterschalten
Auf Basis des Zeitmanagers soll nun die Möglichkeit geschaffen werden, die Zeit in Tagesschritten weiterzuschalten. Hierfür wird das Menü des Shopfensters erweitert. Dem in Abschnitt Das Menü des Ladens geschaffenen Untermenü Videoautomat wird ein Eintrag hinzugefügt, bei dessen Betätigung die Zeit um 24h vorgestellt wird. Die Methode createShopMenuSheet()
in der Klasse VideoShop
wird wie folgt erweitert.
protected MenuSheet createShopMenuSheet() { MenuSheet ms_default = super.createShopMenuSheet(); MenuSheet ms_new = new MenuSheet(MS_NEW); . . . MenuSheetItem msi_time = new MenuSheetItem(MSI_DAY, new Action() { public void doAction(SaleProcess p, SalesPoint sp) throws Throwable { getTimer().goAhead(); } }); ms_new.add(msi_time); ms_default.add(ms_new); return ms_default; }
Außerdem muss die Bezeichnung des Menüeintrags wieder als Konstante definiert werden.
public static final String MSI_DAY = "+ 1 Day";
Die vom Zeitmanager verwendete Methode goAhead()
in der Aktion des neuen Menüeintrags erhöht die Zeit um einen zuvor definierten Intervall. Sofern noch kein Intervall definiert ist, wird der Standardintervall des internen Zeitobjekts, hier das CalendarTime
-Objekt, genutzt. Wie es der Zufall will, entspricht der Standardintervall der Klasse CalendarTime
genau 24h, so dass in diesem Fall keine Anpassungen vorgenommen werden müssen.
Um Überprüfen zu können, ob die Weiterschaltung korrekt funktioniert bzw. um bei weiteren Tests die Übersicht über das aktuelle Datum zu behalten, muss die Zeit irgendwo angezeigt werden. Dafür wird die Titelleiste des Shopfensters im Konstruktor von VideoShop
angepasst.
public class VideoShop extends Shop { . . . public VideoShop() { . . . setShopFrameTitle(getTimer().getTime().toString()); } . . . }
Der Aufruf bewirkt, dass das Datum zum Startzeitpunkt der Anwendung korrekt angezeigt wird. Bei einer Änderung des Datums ändert sich die Anzeige jedoch nicht. Somit muss bei der Weiterschaltung der Zeit die Anzeige ebenfalls auffgefrischt werden. Hierfür wird der vorangegangene Aufruf in der Methode createShopMenuSheet()
ergänzt.
protected MenuSheet createShopMenuSheet() { MenuSheet ms_default = super.createShopMenuSheet(); MenuSheet ms_new = new MenuSheet(MS_NEW); . . . MenuSheetItem msi_time = new MenuSheetItem(MSI_DAY, new Action() { public void doAction(SaleProcess p, SalesPoint sp) throws Throwable { getTimer().goAhead(); setShopFrameTitle(getTimer().getTime().toString()); } }); ms_new.add(msi_time); ms_default.add(ms_new); return ms_default; }
Nach erfolgter Übersetzung und Ausführung kann die Zeit in der Titelleiste des Shopfensters betrachtet und über das Menü weitergeschaltet werden.
Das Geld | Die Leih-Kassette |