Montag, 26. Januar 2009

Unser Projekt in Zahlen und Schlagworten

Eine Woche ist unser Projekt nun schon alt, und damit wohl auch wieder großteils in Vergessenheit geraten. Das Design ist übrigens natürlich überhaupt nicht geklaut, sondern wahrt nur die Corporate Identity!

Abschließend folgt noch eine kleine Statstik über die Verteilung der LOCs in den einzelnen Paketen:

PaketFunktionalitätLOC



ActionAnwendungsfälle (15 Stück!)490
ModelPlain PHP Objects (Attribute, getter, setter)320
Framework
560

Persistenz(230)

Presenter(120)

Controller(90)

Session Verwaltung (Authentication, Identity, Session)(120)
ViewHTML Seiten800



Summe
2170


Im Vergleich mit P3 und P5 sieht man sehr schön, dass die geplante Architektur eingehalten werden konnte und somit eine schöne Kapselung von Zuständigkeiten vorliegt.

Wer sich unser Projekt genauer ansieht, wird beispielsweise feststellen dass wir trotz Datenbank keine vordefinierten SQL Statements verwenden (ORM sei Dank :)). Den Source findet ihr als ZIP hier.

Hier ein paar inhaltsleere Schlagwörter (sinngemäß © Review-Partnerteam), die unser Projekt auszeichnen.
  • URL Rewriting
  • Front Controller
  • SQLLite DB
  • Objektrelationales Mapping (ORM)
  • Templatesystem mit Push und Pull - Ansatz
  • Intensive Singleton Verwendung
  • (Pseudo) Dependency Injection durch Abruf der Singleton Instanzen im Konstruktor der abhängigen Klassen und Referenzierung in privaten Klassenattributen.
  • Interfaces (Klasse Persistence), Abstrakte Basisklassen
  • Class Hints
  • Magische __get() Methoden (zB zur Auflösung von ForeignKeys in Objekte im Rahmen der ORM)
  • Reflection (zb beim Bau der SQL - Statements)
  • AJAX Anzeige freier Plätze (zwecks besserer Vorführbarkeit alle 2 Sekunden randomisiert zwischen 1 und 400)
Durch das mächtige Framework und die Abstrahierung kann sehr einfach produktiv an der Implementierung der Anwendungsfälle (Businees-Logik) gearbeitet werden.

Meine Teamkollegen hat es gefreut, umso mehr da sie zu Beginn des Semesters noch gar keine Ahnung von PHP hatten und durch Zurückgreifen auf bereitgestellte Kernfunktionalität nicht mit Low-Level-Implementierungsdetails überfordert wurden.

Freitag, 16. Januar 2009

WSDL: Eine Nachbetrachtung

Alle Jahre wieder gibt es neue Blogeinträge so wie hier dieser. Fast vier Wochen ist es her, dass ich vom Almighty Webservice Client berichtet habe, und jetzt ist es Zeit für neue Meldungen.

Während kurz vor der Deadline noch alles wunderbar funktioniert hat, meldete sich der Client in den frühen Morgenstunden und am Vormittag darauf mit einem Error. Grund dafür war, dass einige Kollegen ihre fehlerhaften Webservices offenbar gelöscht haben, sodass SoapClient nur einen HTTP 404 Fehler anstatt einer brauchbaren Description XML vorfinden konnte. Da diese Möglichkeit im Client schlicht und einfach nicht berücksichtigt wurde, verwundert das Verhalten auch nicht weiter. Inzwischen ist die Liste der Webservices zwar geschrumpft, dafür aber auch wieder fehlerlos.

Gegen Ende des letzten Jahres hatte ich dann noch die Idee, man könnte doch auch einen generischen Server erstellen. Das klingt zuallererst einmal total verrückt, und ich distanziere mich auch hohoffiziell von jeglicher gedanklicher Inbeziehungstellung mit Sekt oder dergleichem. Technisch ist das aber durchaus machbar.

Wie wir inzwischen wissen sollten, erfolgt die Zuordnung zu einer Klasse zB mit $server->setClass("MissWorld"), die Operationen anhand ihres Namens in Methodenaufrufe übersetzt. Wenn die Operation also "schaffeWeltfrieden" heißt dann wird vom SoapServer Proxy die $missWorldInstance->schaffeWeltfrieden(); Implementierung aufgerufen.

Aber... da müsste man doch die Klasse mit allen je möglichen Operationen/Methoden ausstatten, und das geht ja gar nicht !? Klar, das müsste man, und das kann man mit Hilfe einer magischen Methode (ja, die heißt wirklich auch offiziell so!) machen, nämlich __call():

"__call() is triggered when invoking inaccessible methods in an object context."
http://us.php.net/manual/en/language.oop5.magic.php
Mit Hilfe der aus dem Almighty Client bekannten Parserei schauen wir dann nach, wie der retournierte Typ aussehen muss (primitiver Wert bzw. ComplexType). Die Generierung der Daten erfolgt dann entweder randomisiert oder durch Wiederverwendung der Eingabedaten.

Die Server Klasse könnte dann ungefähr folgendermaßen aussehen, wobei hier davon ausgegangen wird, dass die Argumente primitive Typen und keine Arrays sind, und dass der Rückgabewert ein nicht verschachtelter ComplexType mit primitiven Attributen ist:

class AlmightyServer
{
public function
__call($name, $arguments)
{
$object = WsdlParser::getReturnObjectFor($name);
foreach(get_object_vars($object) as $key=>$value)
{
$object->$key = $arguments[ rand( 0,count($arguments) ) ];
}
return $object;
}
}


Daraus ist aber dann nichts geworden, unter anderem weil das Teamprojekt gerufen hat. Aber davon erst am Wochenende mehr.