Facade

Паттерн, который прячет сложную подсистему за одним простым входом — «одна кнопка вместо десяти рычагов».

Facade предоставляет упрощённый единый интерфейс к набору классов сложной подсистемы.

Какую задачу решает

Чтобы оформить заказ, надо проверить склад, списать оплату, зарезервировать товар и отправить письмо — четыре разные подсистемы. Если клиент вызывает их вручную в правильном порядке, он связан со всеми четырьмя и легко ошибётся. Facade прячет этот оркестр за одним методом place_order().

Идея и реализация

class Inventory:
    def reserve(self, item):
        print(f"Зарезервирован товар: {item}")


class Payment:
    def charge(self, amount):
        print(f"Списано: {amount} руб.")


class Mailer:
    def send(self, item):
        print(f"Письмо о покупке «{item}» отправлено")


class ShopFacade:                # фасад над тремя подсистемами
    def __init__(self):
        self.inventory = Inventory()
        self.payment = Payment()
        self.mailer = Mailer()

    def place_order(self, item, amount):
        self.inventory.reserve(item)
        self.payment.charge(amount)
        self.mailer.send(item)
        print("Заказ оформлен")


ShopFacade().place_order("книга", 590)

Вывод:

Зарезервирован товар: книга
Списано: 590 руб.
Письмо о покупке «книга» отправлено
Заказ оформлен

Клиенту теперь нужен один объект и один вызов. Порядок шагов и знание о подсистемах спрятаны внутри фасада. Важно: фасад не запрещает доступ к подсистемам напрямую — он лишь предлагает удобный путь для типового сценария.

Фасад особенно ценен на границах модулей. Когда команда A пользуется кодом команды B, удобно, если у модуля B есть один продуманный «парадный вход», а не россыпь внутренних классов, которые приходится вызывать в правильном порядке. Фасад фиксирует поддерживаемый сценарий использования и оставляет команде B свободу менять внутренности подсистемы, не ломая клиентов, — пока сигнатура фасада неизменна.

Facade против Adapter

FacadeAdapter
Упрощает: новый простой интерфейс к сложной подсистемеСогласует: чужой интерфейс к ожидаемому
Обычно оборачивает много классовОбычно оборачивает один объект
Цель — удобствоЦель — совместимость

Плюсы и минусы

  • Плюс: снижает связанность клиента с подсистемой; код проще читать и тестировать.
  • Минус: фасад может разрастись в «божественный объект», если тянуть в него слишком много.

Где встречается

Высокоуровневые SDK поверх низкоуровневых API (requests прячет сложность HTTP), сервисный слой над репозиториями в приложениях, библиотечные функции вроде json.dumps, скрывающие машину сериализации.

Итог

  • Facade — простой вход в сложную подсистему.
  • Отличается от Adapter целью: удобство против совместимости.
  • Снижает связанность, но не должен превращаться в «бога».
Проверьте себя
1. Что предоставляет Facade?
AЕдинственный экземпляр класса
BУпрощённый единый интерфейс к сложной подсистеме
CКопию объекта
DСписок подписчиков
2. Чем Facade отличается от Adapter по цели?
AНичем
BFacade упрощает доступ к подсистеме, а Adapter согласует несовместимый интерфейс
CFacade всегда один объект
DAdapter медленнее
3. Какой риск у Facade?
AОн замедляет систему
BОн может разрастись в «божественный объект»
CОн запрещает доступ к подсистеме
DОн требует наследования
Поддержать проект