am 25. August 2009
Ich weiß ja, dass ihr die Programmierthemen am liebsten mögt (habe ich an der regen Kommentar Beteiligung von gestern ableiten können), deswegen wollen wir uns heute mal wieder den Entwurfsmuster widmen. Beim Fassaden Muster geht es darum Komplexität vom Anwender fern zu halten, sie also zu reduzieren. Zumindest ist das einer der Hauptvorteile.
Ihr kennt das vielleicht auch. Ihr habt eine Klasse, die alles kann. Ihr wollt aber eigentlich nur ein minimales Subset des Interfaces zur Verfügung stellen. Vielleicht wollt ihr auch einfach Funktionalitäten entfernen, weil die Verwendung an dieser Stelle eh verboten ist. Userdaten speichern in der View Schicht zum Beispiel. Ganz fiese Sache. Nehmen wir uns also ein ziemlich einfaches User Modell:
class User
{
public function __construct( $userId )
{
// ...
}
public function getName( )
{
// ...
}
public function store( )
{
// ...
}
}
Wenn ich ein User Objekt jetzt an die View übergebe (oder sie es sich holt), dann sollte die Methode store() dort nicht mehr aufrufbar sein, denn keine Logik in der Ausgabeschicht. Ganz naiv könnte man ja jetzt sagen, dass wir einfach Ableiten und die Methode store private machen. Geht aber nicht, weil wir da gegen eines der wichtigsten OOP Prinzipien verstoßen. Jede abgeleitete Klasse verhält sich nach außen wie ihre Eltern-Klasse. Mathematisch: Sei q(x) eine beweisbare Eigenschaft von Objekten x des Typs T. Dann soll q(y) für Objekte y des Typs S wahr sein, wobei S ein Untertyp von T ist. Klingt klug ,oder? Ist aber nur abgeschrieben. Werde da trotzdem bald mal näher drauf eingehen.
Aber wieder zu unserem eigentlichen Problem. Wir wollen die store Methode wegbekommen. Das Zauberwort heißt hier, wie in vielen anderen Fällen auch, Delegation.
class ReadOnlyUserFacade
{
private $user;
public function __construct( $userId )
{
$this->user = new User( $userId );
}
public function getName( )
{
return $this->user->getName( );
}
}
Fertig. Wenn ihr jetzt ganz sauber arbeiten wollt, dann baut ihr euch noch zwei Interfaces. iReadOnlyUser und iUser extends iReadOnlyUser. Dann passt das nämlich auch wieder wunderbar in das durchgängige OOP Konzept, was wir ja alle so lieben. Ist doch echt eine feine Sache, wir haben die User Klasse nicht angefasst und trotzdem haben wir die Methode wegnehmen können.
Wenn man ein wenig weiter nachgrübelt, dann fallen einem bestimmt noch viele weitere Punkte ein, wo man dieses Entwurfsmuster verwenden kann. Sicherheit, saubere Trennung von view und controller, Reduzierung der Komplexität, und und und.