Facade (Фасад)¶
Категория: структурный паттерн.
Проблема¶
Подсистема состоит из многих взаимосвязанных классов, и для выполнения одного типового сценария клиенту приходится знать порядок вызовов, правильно передавать данные между несколькими объектами и следить за деталями, которые к его собственной задаче прямого отношения не имеют. Это создаёт сильную связанность между клиентским кодом и внутренним устройством подсистемы: любое изменение внутри подсистемы рискует сломать код всех, кто её использует.
Решение¶
Вводится класс-фасад, который: 1. Знает о всех классах подсистемы, необходимых для типового сценария. 2. Предоставляет один (или несколько) простых метода, реализующих этот сценарий целиком. 3. Прячет внутри себя порядок вызовов, обработку промежуточных результатов и детали взаимодействия компонентов подсистемы.
При этом сама подсистема остаётся доступной напрямую для тех, кому нужен нестандартный сценарий или более тонкий контроль - фасад не запрещает прямой доступ, а лишь даёт упрощённый путь для типовых случаев.
Структура¶
Subsystem classes- набор классов со своей логикой и взаимными зависимостями.Facade- единая точка входа с упрощёнными методами для типовых сценариев.Client- в большинстве случаев работает черезFacade, но при необходимости может обратиться к классам подсистемы напрямую.
Когда применять¶
- Нужно дать простой интерфейс к сложной подсистеме для наиболее частых сценариев использования.
- Требуется уменьшить связанность между клиентским кодом и внутренними деталями подсистемы, чтобы подсистему можно было менять, не затрагивая клиентов фасада.
- Подсистема "слоится" на уровни, и фасад можно использовать как точку входа в каждый слой.
Плюсы¶
- Изолирует клиентский код от сложности и деталей реализации подсистемы.
- Уменьшает количество зависимостей, о которых должен знать клиент.
- Позволяет менять внутреннее устройство подсистемы, не трогая клиентский код, если публичный контракт фасада не меняется.
Минусы¶
- Фасад рискует превратиться в "божественный объект" (God Object), если в него сваливают всё больше несвязанной логики.
- Не решает проблему сложности - лишь прячет её за более удобным интерфейсом; сама подсистема продолжает быть сложной.
Отличие от Adapter¶
Adapter подгоняет интерфейс существующего объекта под уже существующий, ожидаемый интерфейс - обычно для одного объекта. Facade создаёт новый, более простой интерфейс для сценариев, использующих несколько объектов подсистемы, и не обязан соответствовать какому-либо ранее заданному контракту.
Пример в .NET Framework / BCL¶
HttpClient- фасад над низкоуровневой работой с сокетами, DNS, TLS-рукопожатием и т.д.File/DirectoryвSystem.IO- фасад над более низкоуровневымиFileStream,FileSystemInfoи системными вызовами.- Классы вида
*Service/*Managerв бизнес-логике приложений, скрывающие за собой работу с несколькими репозиториями и внешними клиентами.