Wie man seine Benutzer behandelt 0
Nein, es geht ausnahmsweise mal nicht um Community Management, auch wenn die Überschrift es andeutet. Vielmehr soll es um User Handling bzw. die Nutzerverwaltung gehen, also den Ablauf, wie die Applikation an sich mit den Benutzern umgeht.
Wie bereits erwähnt hat Zeitgeist eine recht komplexe Nutzerverwaltung. Ein Benutzer hat Kerndaten, zum Beispiel Nutzername, Passwort und diverse Schlüssel. Dazu kommen weitere, applikationsabhängige Nutzerdaten, zum Beispiel Vorname, Nachname, Adresse usw. Normalerweise handelt es sich hierbei um 1:1 Beziehungen. Die Daten sind dennoch in eine extra Tabelle ausgelagert und besitzen eine eigene Verwaltung. Der Grund ist, dass man so von Applikation zu Applikation die Nutzerdaten leicht erweitern kann, oder (Beispielsweise bei Webshops mit mehreren Lieferadressen) einfach 1:n Beziehungen abgebildet werden können.
Darüber hinaus hat jeder Benutzer eine Anzahl von Rechten. Rechte sind Beschränkungen bzw. Freigaben von Aktionen der Applikation. Und schließlich hat ein Benutzer eine oder mehrere Rollen: Sammlungen von Rechten.
Unsere Hauptdarsteller sind also: Nutzerverwaltung (der ganze administrative Kram, einschließlich Login, Sicherheit, Nutzervariablen etc.), Nutzerdaten, Nutzerrechte und Nutzerrollen.
Bei der Implementation begannen die Probleme.
Iteration 1: Die Superklasse
Zunächst hatte ich alle Funktionalität in einer Klasse, die alle Aspekte der Benutzerverwaltung vereinigte. Schritt für Schritt aufgebaut wuchs sie langsam, aber stetig. Ich persönlich hasse es, wenn Klassen über eine bestimmte Größe hinauswachsen. Also war der logische Weg: die Klassen aufspalten. Aber wie?
Iteration 2: Aufteilen in einzelne Dateien
Da im Prinzip alle Komponenten zusammenarbeiten, wollte ich eigentlich alles in einer Klasse belassen. Mein erster Gedanke war also die Klasse einfach nur auf einzelne Dateien aufzuteilen und per Include zusammenzufassen.
Schnell zeigte sich: PHP kann zwar Inhalte von Methoden per Include aus externen Dateien einbinden, aber keine Methoden einer Klasse. Klingt zunächst mal komisch, nachdem ich die Kommentare der PHP-Entwickler zu dem Thema gelesen hatte, war mir aber einiges klar. Na gut, also anders.
Iteration 3: Ableitungen und Zuflüsse
Im Grunde ist das Szenario eines der wenigen sinnvollen Anwendungen für Multiple Inheritance, auch bekannt als Mehrfachvererbung. Im Grunde könnte ich die Nutzerdaten, Nutzerrecht und –Rollen einfach in einzelne Klassen packen und eine Benutzer-Klasse darüber von allen drei erben lassen. Doch, richtig, PHP kann keine Mehrfachvererbung.
Dem Vorschlag in einem Forum doch lieber Chain Inheritance zu nehmen, habe ich gleich den Vogel gezeigt. Auch Interfaces, die immerhin mehrfach geerbt werden dürfen, bringen mir hier gar nichts.
Iteration 4: Die Rückkehr der Superklasse
Also blieb es bei der Superklasse. Sie funktionierte tadellos und so lange ich keinen Blick in die Datei warf, war alles gut – Bis mir die Situation bei dem letzten Refakturierungslauf endgültig auf die Nerven ging. Ja, wir reden hier von einem ästhetischen Problem, aber das ist wohl bezeichnend für den Stil von Zeitgeist: Funktionalität und Lesbarkeit gehen Hand in Hand.
Iteration 5: Die Worker-Konstruktion
Also gut. Nutzerdaten, Nutzerrechte und –Rollen sind eigene Klassen. In diesen Klassen ist die jeweilige Logik der Komponenten untergebracht. Die Klassen werden von der Benutzerklasse ganz normal instanziert. Für die Kommunikation der Klassen untereinander sorgt ebenfalls die Benutzerklasse.
Es liegt eigentlich nahe die einzelnen Bereiche einfach in eigene Klassen auszulagern, in so fern frage ich mich, wieso ich es nicht die ganze Zeit so gemacht hatte. Auf der anderen Seite erfordert das Zusammenspiel der Klassen einiges an Overhead, was sich nur durch eine recht clevere Einbindung vermeiden lies: die Klassen werden nur geladen, wenn sie gebraucht werden. Wenn die Nutzerdaten nicht gebraucht werden, wird auch nichts geladen – weder die Klasse, noch die Daten aus der Datenbank.
Dazu kommt noch, dass sich die kleinen, abgeschlossenen Klassen wesentlich besser von den Unit Tests testen lassen.
Fazit
Wieso nicht gleich so? – Weil‘s Aufwand war.
Hat es sich gelohnt? – Auf jeden Fall.
Wird’s dabei bleiben? – Ich hoffe doch! Jetzt habe ich keine Lust mehr, das Ding anzufassen
