Fasada upraszcza oraz unifikuje dostęp do grupy klas lub jednej klasy o rozbudowanym API. Fasada tworzy nowy interfejs o wysokiej abstrakcji, który upraszcza korzystania z całego systemu.

W praktyce z fasadą możemy spotkać się w sytuacji, gdy tworzymy serwis rozdzielony na frontend  oparty na technologiach webowych (Java Script, HTML, CSS, itd.) i backend gdzie komunikacja odbywa się przy pomocy zapytań RESTowych. Wtedy dobrze jest na wejściu backendu zastosować wzorzec Fasada, który dostarczy jedno zunifikowane API, a resztę poupychać po podserwisach odpowiedzialnych za każdy element z danej dziedziny. Fasada może pełnić również rolę adaptera kiedy dokonuje konwersji interfejsu, np. może to wystąpić w przypadku gdy w nowej wersji biblioteki której używamy zostało zastosowane nowe niekompatybilne API.

Zalety:

  • Jeden punkt styku systemu z naszym rozbudowanym systemem. Możemy dokonywać zmian bez konieczności informowania systemu Klienta o tym że coś zmodyfikowaliśmy
  • W przypadku monolitycznego systemu, którego chcemy przerobić na mikroserwisy, na wejściu monolita można postawić fasadę. Możemy wtedy spokojnie przełączać poszczególne elementy naszego systemu bez obawy, że coś u klienta się popsuje.
  • Możemy w jednym miejscu dokonać transformacji danych, logowania co się dzieje
  • Fasada może być również mechanizmem filtrującym, który zatrzyma nie zautoryzowany ruch

Wady:

  • Jak przestanie działać serwis, który stanowi fasadę, to Klient odnosi wrażenie że pada cały system. Ale w praktyce można się przeciw temu zabezpieczyć stosując load balancery, proxy typu High Availability, itd.

Przykład:

System sterowania domem, który implementuje wiele różnych podsystemów, a chcemy mieć jedno uniwersalne API. Więc na wejściu zastosujemy fasadę.

interface Light{
   void on();
 
   void off();
}
 
interface Door{
   void open();
 
   void close();
 
   void lock();
 
   void unlock();
}
 
class HallLight implements Light{
 
   @Override
   public void on(){
 
      System.out.println("Hall light on.");
 
   }
 
   @Override
   public void off(){
 
      System.out.println("Hall light off.");
 
   }
}
 
class LivingRoomLight implements Light{
 
   @Override
   public void on(){
 
      System.out.println("Living room light on.");
   }
 
   @Override
   public void off(){
 
      System.out.println("Living room light off.");
   }
}
 
class MainDoor implements Door{
 
   @Override
   public void open(){
 
      System.out.println("Main door open.");
   }
 
   @Override
   public void close(){
 
      System.out.println("Main door close.");
   }
 
   @Override
   public void lock(){
 
      System.out.println("Main door lock.");
   }
 
   @Override
   public void unlock(){
 
      System.out.println("Main door unlock.");
   }
}
 
class GarageDoor implements Door{
 
   @Override
   public void open(){
 
      System.out.println("Garage door open.");
   }
 
   @Override
   public void close(){
 
      System.out.println("Garage door close.");
   }
 
   @Override
   public void lock(){
 
      System.out.println("Garage door lock.");
   }
 
   @Override
   public void unlock(){
 
      System.out.println("Garage door unlock.");
   }
}
 
class MainApi{
 
   private Light livingRoomLight = new LivingRoomLight();
   private Light hallLight = new HallLight();
   private Door mainDoor = new MainDoor();
   private Door garageDoor = new GarageDoor();
 
   public void lockHome(){
 
      System.out.println("------ LOCK HOME -----");
      livingRoomLight.off();
      hallLight.off();
      mainDoor.lock();
      garageDoor.lock();
   }
 
   public void unlockHome(){
 
      System.out.println("------ UNLOCK HOME -----");
      hallLight.on();
      mainDoor.unlock();
      garageDoor.unlock();
   }
 
   public void lightOff(){
 
      System.out.println("------ LIGHT OFF -----");
      livingRoomLight.off();
      hallLight.off();
   }
 
   public void lightOn(){
 
      System.out.println("------ LIGHT ON -----");
      livingRoomLight.on();
      hallLight.on();
   }
}
 
public class DesignPatternsFacade{
 
   public static void main(String[] args){
 
      MainApi mainApi = new MainApi();
      mainApi.lockHome();
      mainApi.unlockHome();
      mainApi.lightOn();
      mainApi.lightOff();
   }
}