Strukturmuster: Fassade
 
...  [ Seminar Objektorientierter Entwurf]  ...  [ Thema Entwurfsmuster ] ... 
[ Literaturverzeichnis ]  ...
 
bersicht: Strukturmuster: Fassade 
 
Fassade
 ( Facade ) 
 Ist ein objektbasiertes Strukturmuster.
 
Zweck
Es soll für die Anzahl von Schnittstellen eines Subsystems eine einzige
Schnittstelle bieten. Die Fassade vereinfacht so die Benutzung des Subsystems
Motivation
Stellen Sie sich vor, Sie wollen einen Compiler schreiben. Sie haben Scanner- 
und Parserklassen, ein Programmknotenerbauer und Codegeneratorklassen. Alle
diese Klassen werden für den Compiler gebraucht. Nur die Benutzung dieser
Klassen ist aufwendig. Sie müssen jede Klasse erzeugen und die richtigen
Methoden aufrufen, Sie müssen alle Schnittstellen der Klassen kennen.
Zur Vereinfachung ziehen wir diese Klassen zu einem Subsystem zusammen und
setzen eine Klasse Uebersetzer als Schnittstelle ein.
 
Diese Uebersetzer-Klasse stellt dem Klienten eine einfache Schnittstelle(
 Methode Uebersetze() ) zur Verfügung. Sie erzeugt und steuert die Klassen
 des Subsystems, diese Klasse ist die Fassade.
 
Die Fassade dient dazu, zusammengehörige Klassen zu einem Subsystem 
zusammenzufassen. Der Zugriff auf dieses Subsystem wird über eine 
einzige Schnittstelle, die Fassade gesteuert. 
Anwendbarkeit
Verwenden Sie das Fassadenmuster immer dann, wenn
 - Sie ein komplexes Subsystem von Klassen haben, für das Sie eine 
     einfache Schnittstelle anbieten wollen. Die Fassade bietet  einen leichten
     Zugriff auf das Subsystem. Das Subsystem kann dann leichter wiederverwendet
     werden.
 Lediglich für die Funktionalität, die über die Fassade nicht
     erreicht wird, sollten die Klassen direkt angesteuert werden. Die Klienten
     müssen "hinter die Fassade schauen".
- es viele Abhängigkeiten zwischen dem Klient und den
     Implementierungsklassen gibt.
 Die Fassade dient als Entkopplung des Systems und fördert die
     Unabhängigkeit und Portabilität.
- Sie Ihre Subsysteme in Schichten aufteilen wollen.
 Die Fassade dient hier als Eintrittspunkt zu jeder Schicht. Dadurch werden
     die Abhängigkeiten zwischen den Schichten nur auf die Fassade
     begrenzt.
Struktur

 
Teilnehmer
 - Fassade
 
   - steuert Anfragen von Benutzern an das zuständige Subsystemobjekt weiter.
  
 
- Subsystemklassen
  
    - implementieren die Subsystemfunktionalität.
 
- werden von der Fassade aufgerufen.
    
- wissen nichts von der Fassade, d.h. sie besitzen keine Referenz auf die
        Fassade.
   
 
Interaktion
 - Der Klient kommuniziert über die Fassade mit dem Subsystem. Die
     Fassade muß möglicherweise die Aufrufe der Subsystemklassen
     koordinieren um die Funktionalität abzubilden.
 
- Die Klienten sollten die Fassade benutzen. Die Subsystemklassen sollten
     nur direkt aufgrufen werden, wenn die Fassade die gewünschte
     Funktionalität nicht anbietet.
Konsequenzen
 - Das Subsystem wird einfacher nutzbar durch die Reduzierung von zu
     verwaltenden Objekten.
 Es braucht nur die Fassade verwaltet zu werden. Die Fassade schirmt den
     Benutzer von den einzelnen Subsystemkomponenten ab.
- Die lose Kopplung zwischen Klienten und Subsystem wird gefördert.
 Dadurch können Komponenten des Subsystems leichter ausgetauscht
     werden. Es muß nur die Fassade angepaßt werden.
- Der Klient kann entscheiden, ob er die Fassade benutzt oder die
     Subsystemklassen direkt verwendet.
Implementierung
 - Reduzierung der Kopplung zwischen Klient und Subsystem.
 Sie können die Fassade zu einer abstrakten Klasse machen. Die
     konkreten Unterklassen repräsentieren unterschiedliche
     Implementationen des Subsystems. Der Klient kommuniziert mit dem Subsystem
     nur über die Schnittstelle der abstrakten Fassadenklasse, ihm ist 
     nur diese Schnittstelle bekannt.
- Öffentliche oder private Subsystemklassen.
 Eine Klasse kapselt Methoden und Eigenschaften. Ein Subsystem kapselt 
     Klassen. Bei einer Klasse gibt es einen öffentlichen und einen
     privaten Teil der Schnittstelle.
 Auch bei einem Subsystem sollten Sie über einen öffentlichen und
     einen privaten Teil der Schnittstelle nachdenken. Die Fassade gehört
     natürlich zu dem öffentlichen Teil. Aber auch einige
     Subsystemklassen, die von außen zugreifbar sein sollen, gehören
     zum öffentlichen Teil.
 In meinen einführenden Beispiel gehört zum öffentlichen Teil
     der Schnittstelle die Fassade "Uebersetzer", aber auch die Klassen
     Parser und Scanner.
Beispielcode
Die Klassen Scanner um aus einem Zeichenstrom einen Tokenstrom zu erzeugen:
public class Scanner{
        DataInputStream eingabe;
	public Scanner(DataInputStream i){...};
	public Token Scan(){...};
}
Die Klasse Parser benutzt einen ProgrammKnotenErbauer, um einen Parsebaum aus  den Token des Scanners zu erstellen:
public class Parser{
       public Parser(){...}
       public void Parse(Scanner s, ProgrammKnotenErbauer erbauer){...}
     
}
Die Klasse ProgrammKnotenErbauer um den ParseBaum aufzubauen:
class ProgrammKnotenErbauer{
      ProgrammKnoten knoten;
      // die Klasse ProgrammKnoten und ihre Unterklassen
      // (Anweisungsknoten, Ausdrucksknoten) werden als vorhanden 
      // angenommen
      public ProgrammKnotenerbauer(){...}
   
      public ProgrammKnoten NeueVariable(String variablenNamen){...}
      public ProgrammKnoten NeueZuweisung(ProgrammKnoten variable, ProgrammKnoten ausdruck){...}
      public ProgrammKnoten NeueRueckkehrAnweisung(ProgrammKnoten wert){...}
      public ProgrammKnoten NeueBedingteAnweisung(ProgrammKnoten bedingung, ProgrammKnoten wahrZweig, ProgrammKnoten falschZweig){...}
      public ProgrammKnoten GibWurzelKnoten(){...}
}
Die Klasse CodeGenerator (Eine Klasse nach dem Besuchermuster):
class CodeGenerator{
      
      ByteCodeStream ausgabe;  // ByteCodeStream eine eigene Klasse
      public CodeGenerator(ByteCodeStream b){...}
      public void Besuche(AnweisungKnoten anw){...}
      public void Besuche(Ausdrucksknoten aus){...}
      // ....
}
      
Die Fassade-Klasse Uebersetzer :
public class Uebersetzer{
      public Uebersetzer(){..}
      public void Uebersetze(DataInputStream eingabe, ByteCodeStream ausgabe){
            Scanner scanner = new Scanner(eingabe);
            ProgrammKnotenErbauer erbauer;
            Parser parser;
            parser.Parse(scanner, erbauer);
            RISCCodeGenerator generator(ausgabe);
            ProgrammKnoten parsebaum = erbauer.GobWurzelKnoten();
            parseBaum.Traversiere(generator);
      }
}
Bekannte Verwendungen
 - Das Übersetzerbeispiel wurde von Objektworks/Smalltalk-Übersetzer-System inspiriert.
 
- Das Betriebsystem Choices benutzt das Fassadenmuster ausgiebig.
Verwandte Muster
 - Das Abstrakte-Fabrik-Muster kann zusammen mit dem Fassademuster verwendet werden.
 
- Das Vermittlermuster ähnelt dem Fassademuster.
 
- Fassadenobjekte werden meistens als Singletons implementiert.
 
 
 
 
...  [ Seminar Objektorientierter Entwurf]  ...  [ Thema Entwurfsmuster ]  ...  [ Strukturmuster: Fassade]  ...  [ Literaturverzeichnis ]  ...