Strin 1 – nøgleord
Definition af nøgleord er den hemmelige opskrift i denne serie af quick-guides. Denne metode hjalp mig til virkelig at forstå designmønstrene, hardcode dem i mit sind og forstå forskellene mellem andre designmønstre.
- Forenkling: Dette er målet med dette designmønster. At forenkle et kompliceret system.
- Begrænsning: Forenkling kommer ofte med en “hellig omkostning”, nemlig begrænsning. Ved at forenkle koden begrænser vi klienterne fra uautoriseret adgang. Derfor forhindrer det dem i at begå fejl, som det ville være svært at opfatte i et kompliceret delsystem.
Der er en afvejning mellem forenkling og begrænsning. Overforenkling af et system betyder, at udvikleren bliver overbegrænset, altså mindre frihed end nødvendigt, hvilket ikke altid er en god ting. Under-simplificering af Facade-mønsteret betyder, at der er for stor frihed, hvilket gør Facade-mønsteret irrelevant. At finde den fine balance er det, der gør et godt, brugbart og effektivt Facade-mønster.
Strin 2 – Diagram
Diagrammet er også baseret på det givne eksempel. For at forenkle dette diagram kan vi opdele det i tre dele:
- Klient: Klienten i dette eksempel er kunden i en restaurant, der ønsker at bestille mad.
- Facade: Det er dens opgave at kunne give klienten en mere forenklet adgang til mange indbyrdes afhængige delsystemer, der betragtes som komplicerede. I dette eksempel vil en kundes bestilling af mad kræve en række omhyggeligt sekventerede metodekald fra to forskellige undersystemer (tjener og køkken).
- Undersystemer: Undersystemerne er skjult for klienten. De er måske heller ikke tilgængelige for klienten. Klienten kan ikke pille ved nogen af delsystemerne, hvor en simpel kodeændring kan vise sig at være fatal eller endog ødelægge andre ukendte dele af selve systemet. I dette scenario skal tjeneren og køkkenet udføre en række opgaver. Et delsystems opgave er undertiden afhængig af et andet delsystems opgave. F.eks. kan køkkenet ikke tilberede maden, hvis tjeneren ikke bringer bestillingen til køkkenet. Tjeneren kan ikke betjene kunden, hvis maden ikke er tilberedt.
Stræk 3 – Kode ved eksempel
Jeg vil foreslå at kopiere koden klasse for klasse fra mit git-repositorium “Andreas Poyias” eller nedenstående uddrag (i den angivne rækkefølge) og indsætte den i en af de tilgængelige online C++-editorer som c++shell, jdoodle , onlineGDB og køre den for at observere output. Læs derefter kommentarerne eller beskrivelsen nedenfor. Tag dig god tid til at læse den grundigt (det vil sige et minut, ikke mindre og ikke mere).
Subsystemer
I dette eksempel er de to subsystemer Waiter_Subsystem1
og Kitchen_Subsystem2
. Ved første øjekast ser hvert delsystem ud til at være uafhængigt, da de kan udføre visse opgaver hver for sig. Men er dette sandt?
#include <iostream>
using namespace std;class Waiter_Subsystem1
{
public:
void writeOrder() { cout << " Waiter writes client's order\n";}
void sendToKitchen(){ cout << " Send order to kitchen\n";}
void serveCustomer(){ cout << " Yeeei customer is served!!!\n";}
};class Kitchen_Subsystem2
{
public:
void prepareFood(){ cout << " Cook food\n";}
void callWaiter() { cout << " Call Waiter\n";}
void washDishes() { cout << " Wash the dishes\n";}
};
Facade: I dette eksempel handler Facade-klassen om mad-bestillinger i restauranten. For at udføre en madbestilling med succes er vi afhængige af en bestemt sekvens af metodeopkald, og det ene opkald er afhængigt af det foregående og så videre. Køkkenet kan ikke tilberede maden, hvis tjeneren ikke skriver bestillingen og sender den til køkkenet. Facade-klassen giverorderFood
opgaven til klienten for at forenkle den og undgå misbrug på grund af den kompleksitet, der findes.
class Order_Facade
{
private:
Waiter_Subsystem1waiter;
Kitchen_Subsystem2 kitchen;
public:
void orderFood()
{
cout << "A series of interdependent calls on various subsystems:\n";
waiter.writeOrder();
waiter.sendToKitchen();
kitchen.prepareFood();
kitchen.callWaiter();
waiter.serveCustomer();
kitchen.washDishes();
}
};
Hovedfunktion
Hovedfunktionen fungerer som klient(det samme som de foregående vejledninger). Det er så nemt for klienten at kunne oprette en Facade-instans og kalde en funktion for at udføre sit arbejde.
int main(int argc, char *argv)
{
// Simple for the client
// no need to know the order or the
// dependencies among various subsystems.
Order_Facade facade;
facade.orderFood();return 0;
}// Output
// A series of interdependent calls on various subsystems:
// Waiter writes client's order
// Send order to kitchen
// Cook food
// Call Waiter
// Yeeei customer is served!!!
// Wash the dishes
Der er et par fordele ved brugen af Facade-mønsteret og et par punkter at være opmærksom på, når man skal nærme sig Facade.
- Facade definerer en grænseflade på et højere niveau, der gør delsystemet lettere at bruge ved at indpakke et kompliceret delsystem.
- Dette reducerer den indlæringskurve, der er nødvendig for at udnytte delsystemet med succes.
- Det fremmer også afkoblingen af delsystemet fra dets potentielt mange klienter.
- På den anden side vil Facade, hvis Facade er det eneste adgangspunkt for delsystemet, begrænse de funktioner og den fleksibilitet, som “power users” kan have brug for.
Den næste blog vil være en hurtig guide til Observer-designmønsteret. Det er et adfærdsmønster, som er et must have til dit videnslager. Glem ikke at like/klappe mit blog-indlæg og følge min konto. Dette er for at give mig den tilfredsstillelse, at jeg hjalp nogle medudviklere og skubbe mig til at fortsætte med at skrive. Hvis der er et specifikt designmønster, som du gerne vil lære om, så lad mig vide det, så jeg kan levere det til dig i fremtiden.
Andre quick-guides om designmønstre:
- Designmønstre – En quick guide til Abstract Factory.
- Designmønstre – En quick guide til Bridge Pattern.
- Designmønstre – En hurtig guide til Builder-mønsteret.
- Designmønstre – En hurtig guide til Decorator-mønsteret.
- Designmønstre – En hurtig guide til Facade-mønsteret.
- Designmønstre – En hurtig guide til Observer-mønsteret.
- Designmønstre – En hurtig guide til Singleton-mønsteret.