Entwurfsmuster - Eine Kurzanleitung für Fassadenmuster.

Fassadenmuster werden häufig benötigt, wenn eine große Anzahl voneinander abhängiger Klassen vorhanden ist oder Teile des Codes nicht verfügbar sind. Es wird als Tarnung verwendet, um die Komplexität eines großen Systems abzudecken, und bietet daher eine einfache Schnittstelle zum Client. Mit anderen Worten, es ist eine Wrapper-Klasse, mit der die Implementierungsdetails ausgeblendet werden.

Das Fassadenmuster wird als strukturelles Entwurfsmuster klassifiziert. Bei diesem Entwurfsmuster dreht sich alles um die Zusammensetzung von Klassen und Objekten. Strukturelle Klassenerstellungsmuster verwenden die Vererbung, um Schnittstellen zu erstellen. Strukturelle Objektmuster definieren Möglichkeiten zum Zusammensetzen von Objekten, um neue Funktionen zu erhalten. [von Design Patterns einfach erklärt]

Das Bild oben ist das perfekte Beispiel für ein Fassadenmuster. Ein Kunde in einem Restaurant bestellt Lebensmittel aus der Speisekarte, die wahrscheinlich in einer halben Zeile beschrieben wird. Die Bestellung geht in die Küche und das Essen kommt nach einer Weile zurück. Einfach! Der Kunde möchte nicht wissen, wer das Fleisch wie lange schneidet und wer das Geschirr danach spült. Der Kunde möchte nur eine leckere Mahlzeit zu sich nehmen, die den Erwartungen entspricht. Daher dient das Menü als Fassade, um es dem Kunden zu erleichtern, indem die Komplexität aus der Küche oder sogar die Aufgaben, die dem Kellner durch diesen Prozess zugewiesen werden, vermieden werden.

Schritt 1 - Schlüsselwörter

Die Definition von Schlüsselwörtern ist das Geheimrezept in dieser Reihe von Kurzanleitungen. Diese Methode hat mir geholfen, die Entwurfsmuster wirklich zu verstehen, sie in meinem Kopf fest zu codieren und die Unterschiede zwischen anderen Entwurfsmustern zu verstehen.

  1. Vereinfachung: Dies ist das Ziel dieses Entwurfsmusters. Vereinfachen Sie ein kompliziertes System.
  2. Einschränkung: Vereinfachung ist oft mit „heiligen Kosten“ verbunden, einer Einschränkung. Durch die Vereinfachung des Codes verhindern wir, dass Clients nicht autorisiert darauf zugreifen können. Dadurch wird verhindert, dass sie Fehler machen, die in einem komplizierten Subsystem nur schwer zu erkennen sind.

Es gibt einen Kompromiss zwischen Vereinfachung und Einschränkung. Eine zu starke Vereinfachung eines Systems bedeutet, dass der Entwickler übermäßig eingeschränkt ist, was nicht immer gut ist. Eine zu geringe Vereinfachung des Fassadenmusters bedeutet, dass zu viel Freiheit vorhanden ist, was das Fassadenmuster irrelevant macht. Das Finden der feinen Balance ist das, was ein gutes, nützliches und effektives Fassadenmuster ausmacht.

Schritt 2 - Diagramm

Das Diagramm basiert ebenfalls auf dem angegebenen Beispiel. Um dieses Diagramm zu vereinfachen, können wir es in drei Teile unterteilen.

  1. Kunde: Der Kunde in diesem Beispiel ist der Kunde eines Restaurants, das Essen bestellen möchte.
  2. Fassade: Ihre Aufgabe ist es, dem Kunden einen einfacheren Zugang zu zahlreichen voneinander abhängigen Teilsystemen zu ermöglichen, die als kompliziert gelten. In diesem Beispiel würde die Bestellung eines Kunden eine Reihe sorgfältig aufeinanderfolgender Methodenaufrufe von zwei verschiedenen Subsystemen (Kellner und Küche) erfordern.
  3. Subsysteme: Die Subsysteme sind vor dem Client verborgen. Sie sind möglicherweise auch für den Kunden nicht zugänglich. Der Client kann mit keinem der Subsysteme herumspielen, bei denen sich eine einfache Codeänderung als schwerwiegend erweisen oder sogar andere unbekannte Teile des Systems selbst beschädigen kann. In diesem Szenario müssen der Kellner und die Küche eine Reihe von Aufgaben ausführen. Die Aufgabe eines Subsystems ist manchmal von der Aufgabe eines anderen abhängig. Beispielsweise kann die Küche das Essen nicht zubereiten, wenn der Kellner die Bestellung nicht in die Küche bringt. Der Kellner kann den Kunden nicht bedienen, wenn das Essen nicht gekocht ist.

Schritt 3 - Code durch Beispiel

Ich würde vorschlagen, den Code Klasse für Klasse aus meinem Git-Repository "Andreas Poyias" oder den folgenden Ausschnitten (in der angegebenen Reihenfolge) zu kopieren und in einen der verfügbaren Online-C ++ - Editoren wie c ++ shell, jdoodle, onlineGDB einzufügen und auszuführen es, um die Ausgabe zu beobachten. Dann lies die Kommentare oder die Beschreibung unten. Nehmen Sie sich Zeit und lesen Sie es gründlich durch (das bedeutet eine Minute, nicht weniger und nicht mehr).

Subsysteme

In diesem Beispiel sind die beiden Subsysteme das Waiter_Subsystem1 und das Kitchen_Subsystem2. Auf den ersten Blick scheint jedes Subsystem unabhängig zu sein, da es bestimmte Aufgaben einzeln ausführen kann. Aber ist das wahr?

#include 
using namespace std;
Klasse Waiter_Subsystem1
{
Öffentlichkeit:
  void writeOrder () {cout << "Kellner schreibt Kundenbestellung \ n";}
  void sendToKitchen () {cout << "Bestellung an Küche senden \ n";}
  void serveCustomer () {cout << "Yeeei Kunde wird bedient !!! \ n";}
};
Klasse Kitchen_Subsystem2
{
Öffentlichkeit:
    void prepareFood () {cout << "Essen kochen \ n";}
    void callWaiter () {cout << "Call Waiter \ n";}
    void washDishes () {cout << "Geschirr spülen \ n";}
};

Fassade: In diesem Beispiel geht es in der Klasse Fassade um Essensbestellungen im Restaurant. Um eine Lebensmittelbestellung erfolgreich auszuführen, sind wir auf eine bestimmte Folge von Methodenaufrufen angewiesen, und ein Aufruf ist vom vorherigen abhängig und so weiter. Die Küche kann das Essen nicht zubereiten, wenn der Kellner die Bestellung nicht schreibt und sie in die Küche schickt. Die Facade-Klasse stellt dem Client die OrderFood-Aufgabe zur Verfügung, um sie zu vereinfachen und Missbrauch aufgrund der vorhandenen Komplexität zu vermeiden.

Klasse Order_Facade
{
Privatgelände:
    Waiter_Subsystem1waiter;
    Kitchen_Subsystem2 Küche;
Öffentlichkeit:
    storniere orderFood ()
    {
        cout << "Eine Reihe von voneinander abhängigen Aufrufen auf verschiedenen Subsystemen: \ n";
        waiter.writeOrder ();
        waiter.sendToKitchen ();
        kitchen.prepareFood ();
        kitchen.callWaiter ();
        waiter.serveCustomer ();
        kitchen.washDishes ();
    }
};

Hauptfunktion
Die Hauptfunktion fungiert als Client (wie in den vorherigen Handbüchern). Es ist für den Kunden so einfach, eine Facade-Instanz zu erstellen und eine Funktion aufzurufen, um seine Arbeit zu erledigen.

int main (int argc, char * argv [])
{
    // Einfach für den Client
    // keine Notwendigkeit, die Reihenfolge oder die zu kennen
    // Abhängigkeiten zwischen verschiedenen Subsystemen.
    Order_Facade Fassade;
    facade.orderFood ();
return 0;
}
// Ausgabe
// Eine Reihe von voneinander abhängigen Aufrufen für verschiedene Subsysteme:
// Kellner schreibt Kundenbestellung
// Bestellung in die Küche schicken
//  Essen kochen
// Kellner anrufen
// Yeeei Kunde wird bedient !!!
//  Wasche das Geschirr

Die Verwendung von Fassadenmustern bietet einige Vorteile und einige Punkte, die zu beachten sind, wenn die Fassade angefahren werden soll.

  • Facade definiert eine übergeordnete Schnittstelle, die die Verwendung des Subsystems erleichtert, indem ein kompliziertes Subsystem eingeschlossen wird.
  • Dies reduziert die Lernkurve, die erforderlich ist, um das Subsystem erfolgreich einzusetzen.
  • Es fördert auch die Entkopplung des Subsystems von seinen potenziell vielen Clients.
  • Wenn die Fassade andererseits der einzige Zugangspunkt für das Subsystem ist, werden die Funktionen und die Flexibilität eingeschränkt, die „Hauptbenutzer“ möglicherweise benötigen.

Der nächste Blog bietet eine kurze Einführung in das Designmuster von Observer. Es handelt sich um ein Verhaltensmuster, das in Ihrem Wissensrepository nicht fehlen darf. Vergiss nicht, meinen Blog-Post zu mögen / zu klatschen und meinem Account zu folgen. Dies soll mir die Befriedigung geben, dass ich einigen Mitentwicklern geholfen habe und mich dazu drängen, weiter zu schreiben. Wenn es ein bestimmtes Designmuster gibt, über das Sie gerne mehr erfahren möchten, lassen Sie es mich wissen, damit ich es in Zukunft für Sie bereitstellen kann.

Weitere Kurzanleitungen zu Entwurfsmustern:

  1. Design Patterns - Eine Kurzanleitung für Abstract Factory.
  2. Design Patterns - Eine Kurzanleitung für Bridge Pattern.
  3. Entwurfsmuster - Eine Kurzanleitung zum Builder-Muster.
  4. Design Patterns - Eine Kurzanleitung für Decorator Patterns.
  5. Entwurfsmuster - Eine Kurzanleitung für Fassadenmuster.
  6. Design Patterns - Eine Kurzanleitung für Observer Patterns.
  7. Entwurfsmuster - Eine Kurzanleitung für Singleton-Muster.