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
| Facade | Adapter |
| Упрощает: новый простой интерфейс к сложной подсистеме | Согласует: чужой интерфейс к ожидаемому |
| Обычно оборачивает много классов | Обычно оборачивает один объект |
| Цель — удобство | Цель — совместимость |
Плюсы и минусы
- Плюс: снижает связанность клиента с подсистемой; код проще читать и тестировать.
- Минус: фасад может разрастись в «божественный объект», если тянуть в него слишком много.
Где встречается
Высокоуровневые SDK поверх низкоуровневых API (requests прячет сложность HTTP), сервисный слой над репозиториями в приложениях, библиотечные функции вроде json.dumps, скрывающие машину сериализации.
Итог
- Facade — простой вход в сложную подсистему.
- Отличается от Adapter целью: удобство против совместимости.
- Снижает связанность, но не должен превращаться в «бога».