Bevor mit dem ersten Prozess der Anwendung, der Nutzerregistrierung, begonnen werden kann, muss die Nutzerverwaltung angelegt werden. Zur Erinnerung: es können lediglich registrierte Kunden am Automaten Filme entleihen. Entsprechend braucht die Anwendung eine Datenstruktur, anhand derer der Automat erkennen kann, wer Kunde ist und wer nicht.
SalesPoint bietet dafür die Klassen User
und UserManager
an.
Der Usermanager
Der Nutzermanager ist eine Art Containerklasse, in der alle Nutzer gespeichert werden. Ebenso wie beim Shop
wurde bei der Klasse UserManager
auf das Entwurfsmuster Singleton zurückgegriffen, d.h. es gibt genau eine Instanz des Nutzermanagers, die über UserManager.getGlobalUM()
referenziert werden kann.
Es wird im Konstruktor von VideoShop
eine neue Instanz von UserManager
erzeugt und zur globalen Instanz erhoben.
public class VideoShop extends Shop { . . . public VideoShop() { . . . UserManager.setGlobalUM(new UserManager()); } . . . }
Der Automatennutzer
Anwender des Programms können durch die Klasse User
dargestellt werden. Ein User
besitzt einen Namen, über den er eindeutig identifiziert werden kann. Darüber hinaus besteht die Möglichkeit ein Passwort zu setzen, sowie Rechte auf mögliche Aktionen zu vergeben.
Damit die entliehenen Videos eines Kunden in der ihn repräsentierenden Instanz gekapselt werden können, muss eine neue Klasse von User
abgeleitet werden. Abgesehen vom Kunden gibt es die Nutzergruppe der Betreiber bzw. Administratoren. Da diese sich im Prinzip nur darin unterscheiden, dass sie über mehr Rechte verfügen, genügt es, eine einzige Klasse für Kunden und Administratoren zu definieren. Die Unterscheidung bezüglich der verschiedenen Rechte erfolgt über einen booleschen Parameter im Konstruktor der neuen Klasse.
package videoautomat; public class AutomatUser extends User { private UserVideoStock ss_videos; public AutomatUser(String user_ID, char[] passWd, boolean admin) { super(user_ID); setPassWd(garblePassWD(passWd)); ss_videos = new UserVideoStock(user_ID, VideoShop.getVideoCatalog()); } public UserVideoStock getVideoStock() { return ss_videos; } }
Im Gegensatz zum VideoShop
werden hier die Videos in einem StoringStockImpl
verwaltet. In einem solchen wird nicht nur die Anzahl gewisser Katalogeinträge gespeichert, sondern es wird jedes einzelne StockItem
separat behandelt. Das ist im Falle der entliehenen Videos unerlässlich, da die Leihzeit jedes einzelnen Videoobjekts erhalten bleiben muss. Die Bestandseinträge der Videos werden über die Klasse VideoCassette
definiert. Deren Implementation erfolgt im Kapitel Die Leih-Kassette. Abgesehen von diesem Unterschied des StoringStockImpl
zum CountingStockImpl
ist der Konstruktoraufruf nahezu identisch.
Ähnlich dem Videokatalog und dem Videobestand des Automaten ist es auch hier zweckmäßig (wegen der Typisierung), eine neue Klasse UserVideoStock
anzulegen, die ebendiese generischen Parameter festlegt:
package videoautomat; public class UserVideoStock extends StoringStockImpl<VideoCassette, CatalogItemImpl> { public UserVideoStock(String sName, CatalogImpl<CatalogItemImpl> ciRef) { super(sName, ciRef); } }
Im Gegensatz zu Katalog und Bestand des Automaten benötigen wir hier keinen eigenen Identifikator, da der UserVideoStock
stets nur beim Nutzer und nie im Shop selbst registriert wird. Deswegen überladen wir auch den String - Konstruktor anstelle des Identifikator - Konstruktors.
Weiterhin ist zu erkennen, dass beim Setzen des Passworts nicht das Passwort selbst, sondern der Rückgabewert der Methode garblePassWD(passWd)
übergeben wird. Dabei handelt es sich um eine Sicherheitsmaßnahme. Damit das Passwort nicht im Klartext abgespeichert wird und ausgelesen werden kann, wird es vorher umschlüsselt. Welcher Algorithmus dabei verwendet wird, kann ebenfalls über die Klasse User
gesetzt werden. Der voreingestellte Algorithmus für die Umschlüsselung ist einfach umkehrbar und daher für sicherheitsrelevante Kontexte nicht zu empfehlen. Wird das Passwort mit der Methode isPassWd(String s)
überprüft, ist darauf zu achten, dass der übergebene String vorher ebenfalls umschlüsselt wird.
Die boolesche Variable wird erst zu einem späteren Zeitpunkt für die Rechtevergabe benötigt.
Um im Folgenden keine Fehlermeldungen zu erhalten, legen wir zumindest erst einmal den Rumpf von VideoCassette
an:
package videoautomat; public class VideoCassette extends StockItemImpl { public VideoCassette(String key) { super(key); } }
Zum Schluss sollen einige Testkunden und ein Administrator der Nutzerverwaltung zugefügt werden. Dafür wird eine Methode in der Klasse MainClass
definiert und in der main-Methode aufgerufen. Als Passwort wird der vereinfachten Testbarkeit halber jeweils eine leere Zeichenkette übergeben.
public static void main(String arqs[]) { . . . initializeUsers(); } public static void initializeUsers() { UserManager.getGlobalUM().addUser(new AutomatUser("Administrator", new char[0], true)); for (int i = 0; i < 10; i++) { UserManager.getGlobalUM().addUser( new AutomatUser("Customer" + i, new char[0], false)); } }
Den Videobestand anzeigen | Die Nutzerregistrierung |