Krok 1 – Słowa kluczowe
Zdefiniowanie słów kluczowych to sekretny przepis w tej serii szybkich przewodników. Ta metoda pomogła mi naprawdę zrozumieć wzorce projektowe, zakodować je w moim umyśle i zrozumieć różnice pomiędzy innymi wzorcami projektowymi.
- Uproszczenie: To jest cel tego wzorca projektowego. Uprościć skomplikowany system.
- Ograniczenie: Uproszczenie często wiąże się ze „świętym kosztem”, ograniczeniem. Upraszczając kod, ograniczamy klientów przed nieautoryzowanym dostępem. Zapobiega to zatem popełnianiu przez nich błędów, które byłyby trudno dostrzegalne w skomplikowanym podsystemie.
Istnieje kompromis między uproszczeniem a ograniczeniem. Nadmierne uproszczenie systemu oznacza, że programista jest nadmiernie ograniczony, a zatem mniej swobody niż to konieczne, co nie zawsze jest dobrą rzeczą. Niewystarczające uproszczenie wzorca Fasady oznacza, że jest zbyt dużo swobody, co sprawia, że wzorzec Fasady staje się nieistotny. Znalezienie odpowiedniej równowagi jest tym, co czyni wzorzec Facade dobrym, użytecznym i efektywnym.
Krok 2 – Diagram
Schemat jest również oparty na podanym przykładzie. Aby uprościć ten diagram możemy rozdzielić go na trzy części.
- Klient: Klientem w tym przykładzie jest klient restauracji, który chce zamówić jedzenie.
- Fasada: Jej zadaniem jest być w stanie zapewnić klientowi bardziej uproszczony dostęp do licznych współzależnych podsystemów, które są uważane za skomplikowane. W tym przykładzie, zamówienie żywności przez klienta wymagałoby serii starannie sekwencjonowanych wywołań metod dwóch różnych podsystemów (Kelner i Kuchnia).
- Podsystemy: Podsystemy są ukryte przed klientem. Mogą być również niedostępne dla klienta. Klient nie może bawić się z żadnym z podsystemów, gdzie prosta zmiana kodu może okazać się zgubna lub nawet złamać inne nieznane części samego systemu. W tym scenariuszu, kelner i kuchnia muszą wykonać serię zadań. Zadanie jednego podsystemu jest czasami zależne od zadania drugiego. Na przykład, kuchnia nie może przygotować jedzenia, jeśli kelner nie przyniesie zamówienia do kuchni. Kelner nie może obsłużyć klienta, jeśli jedzenie nie jest ugotowane.
Krok 3 – Kod na przykładzie
Proponuję skopiować kod klasa po klasie z mojego repozytorium git „Andreas Poyias” lub poniższe fragmenty (w podanej kolejności) i wkleić je do dowolnego z dostępnych edytorów C++ online, takich jak c++shell, jdoodle , onlineGDB i uruchomić go, aby zaobserwować dane wyjściowe. Następnie przeczytaj komentarze lub opis poniżej. Nie spiesz się, czytając go dokładnie (to znaczy minutę, nie mniej i nie więcej).
Podsystemy
W tym przykładzie dwa podsystemy to Waiter_Subsystem1
iKitchen_Subsystem2
. Na pierwszy rzut oka wydaje się, że każdy podsystem jest niezależny, ponieważ może wykonywać pewne zadania indywidualnie. Ale czy to prawda?
#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: W tym przykładzie klasa Facade dotyczy zamówień jedzenia w restauracji. Aby pomyślnie zrealizować zamówienie na jedzenie, polegamy na określonej sekwencji wywołań metod, a jedno wywołanie jest zależne od poprzedniego i tak dalej. Kuchnia nie może przygotować jedzenia, jeśli kelner nie napisze zamówienia i nie wyśle go do kuchni. Klasa Facade dostarczaorderFood
zadania do klienta, aby je uprościć i uniknąć jakichkolwiek nadużyć z powodu złożoności, która istnieje.
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();
}
};
Funkcja główna
Funkcja główna działa jako klient(tak samo jak poprzednie przewodniki). Jest to tak łatwe dla klienta, aby móc stworzyć instancję Facade i wywołać funkcję, aby wykonać swoją pracę.
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
Istnieje kilka korzyści z użycia wzorca Facade i kilka punktów, na które należy zwrócić uwagę, gdy Facade ma być podchodzony.
- Facade definiuje interfejs wyższego poziomu, który sprawia, że podsystem jest łatwiejszy w użyciu poprzez zawijanie skomplikowanego podsystemu.
- Zmniejsza to krzywą uczenia się niezbędną do skutecznego wykorzystania podsystemu.
- Promuje również oddzielenie podsystemu od jego potencjalnie wielu klientów.
- Z drugiej strony, jeśli fasada jest jedynym punktem dostępu do podsystemu, ograniczy funkcje i elastyczność, których mogą potrzebować „zaawansowani użytkownicy”.
Następny blog będzie szybkim przewodnikiem po wzorcu projektowym Observer. Jest to wzorzec behawioralny, który jest obowiązkowym elementem Twojego repozytorium wiedzy. Nie zapomnij polubić/klapnąć mojego bloga i śledzić mojego konta. Ma to na celu dać mi satysfakcję, że pomogłem kilku kolegom programistom i popchnąć mnie do dalszego pisania. Jeśli jest jakiś konkretny wzorzec projektowy, o którym chciałbyś się dowiedzieć, daj mi znać, abym mógł Ci go dostarczyć w przyszłości.
Inne szybkie przewodniki po wzorcach projektowych:
- Wzorce projektowe – Szybki przewodnik po Abstract Factory.
- Wzorce projektowe – Szybki przewodnik po Bridge Pattern.
- Design Patterns – A quick guide to Builder Pattern.
- Design Patterns – A quick guide to Decorator Pattern.
- Design Patterns – A quick guide to Facade Pattern.
- Design Patterns – A quick guide to Observer Pattern.
- Design Patterns – A quick guide to Singleton Pattern.
.