Patterns in der Softwareentwicklung: Das Strukturpattern Fassade
Die Fassade bietet eine vereinfachte Schnittstelle zu einem komplexen System an. Es gehört zu den Strukturmustern.
- Rainer Grimm
Patterns sind eine wichtige Abstraktion in der modernen Softwareentwicklung. Sie bieten eine klar definierte Terminologie, eine saubere Dokumentation und das Lernen von den Besten. Das klassische Buch "Design Patterns: Elements of Reusable Object-Oriented Software" (kurz Design Patterns), das ich in meiner Serie über Muster vorstelle, enthält 23 Muster. Die Fassade ist ein Strukturmuster. und hat einen Zweck: eine vereinfachte Schnittstelle zu einem komplexen System zu schaffen.
Eine Fassade definiert eine übergeordnete Schnittstelle, die die Nutzung des Subsystems erleichtert. Die Absicht der übergeordneten Schnittstelle ist es, nicht alle Anwendungsfälle des komplexen Systems zu unterstützen, sondern nur die wichtigsten. Trotz der Fassade für die vereinfachte Schnittstelle ist es oft noch möglich, das komplexe System direkt zu nutzen.
Die Fassade ist ein idealer Startpunkt, um komplexe Systeme durch die EinfĂĽhrung von Schichten zu entkoppeln. AuĂźerdem kann es als Ausgangspunkt fĂĽr die Abschaffung der alten Schnittstelle verwendet werden
Hier sind die Fakten:
Fassade
Zweck
- Bietet eine vereinfachte Schnittstelle zu einer Reihe von Schnittstellen
Anwendungsfall
- Vereinfachter Zugang zu einem komplexen System
- Ein komplexes System enthält viele Abhängigkeiten, die durch die Fassade entkoppelt werden
- EinfĂĽhrung von Schichten innerhalb eines komplexen Systems; die Schicht hilft, dass komplexe System zu entkoppeln
Struktur
Facade
- Bietet die vereinfachte Schnittstelle an
- Delegiert Anfragen an die Subsysteme
Package
- Implementiert die Funktionalität
- WeiĂź nichts ĂĽber die Fassade
Beispiel
Das folgende Beispiel stammt aus dem Wikibuch C++Programming: code patterns design.
// from https://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/\
Design_Patterns#Facade
#include <string>
#include <iostream>
using namespace std;
class Alarm // (2)
{
public:
void alarmOn()
{
cout << "Alarm is on and house is secured"<<endl;
}
void alarmOff()
{
cout << "Alarm is off and you can go into the house"<<endl;
}
};
class Ac // (3)
{
public:
void acOn()
{
cout << "Ac is on"<<endl;
}
void acOff()
{
cout << "AC is off"<<endl;
}
};
class Tv // (4)
{
public:
void tvOn()
{
cout << "Tv is on"<<endl;
}
void tvOff()
{
cout << "TV is off"<<endl;
}
};
class HouseFacade // (1)
{
Alarm alarm;
Ac ac;
Tv tv;
public:
HouseFacade(){}
void goToWork() // (5)
{
ac.acOff();
tv.tvOff();
alarm.alarmOn();
}
void comeHome() // (6)
{
alarm.alarmOff();
ac.acOn();
tv.tvOn();
}
};
int main()
{
HouseFacade hf;
// Rather than calling 100 different on and off functions
// thanks to facade I only have 2 functions...
hf.goToWork();
hf.comeHome();
}
Die Klasse HouseFacade
(1) vereinfacht die Verwendung der Klassen Alarm
, Ac
und TV
(2 bis 4). Die vereinfachte Schnittstelle besteht aus den beiden Mitgliedsfunktionen goToWork
(5) und comeHome
(6). Beide Mitgliedsfunktionen kapseln nicht nur die zugrunde liegenden Mitgliedsfunktionen der ursprĂĽnglichen Schnittstelle, sondern garantieren auch, dass die Mitgliedsfunktionen in der richtigen Reihenfolge aufgerufen werden.
AbschlieĂźend ist hier die Ausgabe des Programms:
Die Fassade ist wahrscheinlich das am häufigsten verwendete Entwurfsmuster.
Bekannte Verwendungen
Im Allgemeinen kommt die Fassade zum Einsatz, wenn eine Funktion aufgerufen wird, die einen Aufruf des Betriebssystems auslöst. Hier sind ein paar Beispiele:
- Die Container der Standard Template Library verwalten ihren Speicher automatisch.
- Die Threading-API löst Aufrufe der zugrunde liegenden Threading-Infrastruktur wie pthread oder win32 Threads aus.
- Die parallele STL ruft die zugrunde liegende Infrastruktur wie die Threading Building Blocks (TBB) oder die Parallel Patterns Library (PPL) auf.
- Die Dateisystembibliothek ist eine Abstraktion ĂĽber der zugrunde liegenden betriebssystemspezifischen Dateisystembibliothek.
- Es gibt weitere betriebssystemspezifische Abstraktionen. Hier sind einige davon: die Chrono-Bibliothek, die Zufallsbibliothek oder die Formatierungsbibliothek.
Verwandte Muster
- Das Adaptor-Muster passt eine bestehende Schnittstelle an, während die Fassade eine neue, vereinfachte Schnittstelle schafft.
- Eine abstrakte Fabrik ist eine alternative Möglichkeit, ein Subsystem auf transparente Weise zu abstrahieren.
- Das Vermittlermuster koordiniert die Organisation zwischen Objekten, aber die Fassade schafft eine neue, vereinfachte Schnittstelle.
- Das Singleton-Muster kann als einziger Zugangspunkt zu einem komplexen Subsystem dienen.
Vor- und Nachteile
Vorteile
- Die Komplexität des Codes kann vor dem Anwender verborgen werden.
- Die missbräuchliche Nutzung des komplexen Systems wird drastisch reduziert: "Make interfaces easy to use correctly and hard to use incorrectly." von Scott Meyer in seinem Artikel "The Most Important Design Guideline?".
- Es erleichtert es, ein komplexes System auf eine andere Plattform zu portieren, da Anwender nur von der Fassade abhängig sind.
Nachteile
- Eine Fassade kann zu viele Verantwortlichkeiten besitzen und immer mehr zu dem Antipattern God Object mutieren.
- Die Fassade ist dem Singleton-Muster ziemlich ähnlich. Beide bieten einen einzigen Zugangspunkt zu einem komplexen System. Folglich gelten die Vor- und Nachteile des Singleton-Musters auch für das Fassade-Muster. Mehr über die Vor- und Nachteile des Singleton-Musters finden sich in meinem letzten Artikel: "Patterns in der Softwareentwicklung: Die Vor- und Nachteile des Singleton-Musters".
Wie geht's weiter?
In meinem nächsten Artikel stelle ich das verbleibende Strukturmuster aus dem Buch "Design Patterns: Elements of Reusable Object-Oriented Software" genauer vor: das Proxy-Muster. Das Proxy-Muster wird als Platzhalter für den Zugriff auf ein anderes Objekt verwendet. ()