Tag php

Das Zeitgeist Nachrichtensystem 2

Nov23

Jetzt mal ernsthaft – ihr könnt euch ruhig trauen hier im Blog mit Hilfe der Kommentare zu fragen, anstatt mir umständlich eine Mail zu schreiben.

Die Frage war:

Was ist dieses angesprochene Message-System?

Nun, einfach gesagt: Die Message-Klasse stellt Funktionalitäten bereit, um systemweite Textnachrichten zu verwalten.

Das Prinzip der systemweiten Nachrichten sollte vielen bekannt sein, die schon einmal etwas tiefer in die  Dektop-Programmierung eingestiegen sind. Man kann es sich als eine Art Modul vorstellen, das von überall her angesprochen werden kann. An dieses Modul können Nachrichten übergeben und umgekehrt wieder angefordert werden. Auf diese Weise können alle Module eines Projekts miteinander kommunizieren.

Weiterlesen »

Der Zeitgeist Projektaufbau 0

Nov10

Da die Entwicklung der Unit Tests schneller voran geht, als gedacht, habe ich etwas Zeit euch etwas mehr über Zeitgeist zu erzählen.

Ein Projekt mit Zeitgeist ist so aufgebaut:

  • _additional_material: alles, was nicht direkt zum Projekt gehört, aber mit im SVN ist (Konzept, Schemata, etc)
  • classes: Projektspezifische Klassen
  • configuration: Projektspezifische Konfiguration
  • forms: Formularbeschreibungen für den Formularhandler von Zeitgeist
  • includes: Klassen und Module von Dritten
  • modules: Alle Module, die von dem Eventhandler angesprochen werden. In MVC wären das die Models
  • templates: alles, was mit dem Presentation Layer zu tun hat. In MVC die Views
  • tests: Alle Unit Tests landen hier
  • zeitgeist: Das Framework. In MVC hätte es die Controller-Aufgaben

Und um noch einen Blick auf Zeitgeist an sich zu werfen:

Zunächst wären da unter classes alle Core-Klassen von Zeitgeist. Diese werden unabhängig von dem Projekt immer geladen (auch wenn sich die Funktionalität deaktivieren lässt).

  • configuration: Kümmert sich darum, die Konfigurationen eines Projekts zu laden und zu verwalten
  • database: Simple Datenbank-Abstraktionsklasse
  • debug: Debugging, Tracing, Profiling und SQL-Querylogs
  • errorhandler: PHP-Fehlerausgabe (Errors, Warnings)
  • eventhandler: Der Handler, die die Module der Applikation steuert
  • locale: Verwaltet Sprachpakete
  • messagecache/messages: Verwaltet Systemnachrichten
  • objectcache: Verwaltet Objekte. Eine Art Multi-Purpose-Cache
  • parameterhandler: Programmierbarer Eingabefilter
  • session: Verwaltet die Session eines Nutzers
  • template: Simple Template-Engine, basierend auf Dreamweaver Templates
  • trafficlogger: Speichert alle Aufrufe und Zustände
  • userhandler: Kümmert sich (mit den anderen Userklassen) um die Nutzerverwaltung.

In configuration wird Zeitgeist grundsätzlich konfiguriert. Da die Konfiguration in der Applikation selbst überschrieben werden kann, liegt hier nur ein Default-Set.

In includes liegen wieder alle Klassen und Module von Dritten.

In modules liegen alle zusätzlich einbindbaren Module von Zeitgeist: Formularhandler, Payment, Shop, Dispatcher und so weiter. Und schließlich noch die Unit-Tests.

So, das war’s in Kürze. Das sollte als Teaser reichen und vielleicht als Vorlage für einige Fragen dienen.

Wie man seine Benutzer behandelt 0

Aug24

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 :)

Zeitalter3 – Browsergames Entwicklerblog is powered by WordPress
Theme based on FREEmium Theme, developed by Dariusz Siedlecki by FreebiesDock.com