Фасад (Facade)
Facade предоставляет небольшой согласованный интерфейс к нескольким частям подсистемы. Он не прячет существование всех компонентов, а даёт клиенту подходящую точку входа для типового сценария.
Проблема
Без фасада controller может сам координировать:
repository
→ permission checker
→ external client
→ mapper
→ event publisherТогда порядок шагов и обработка ошибки дублируются в нескольких местах.
Пример
public final class ReportFacade {
private final ReportRepository repository;
private final AccessPolicy accessPolicy;
private final ExportClient exportClient;
public ReportFacade(
ReportRepository repository,
AccessPolicy accessPolicy,
ExportClient exportClient
) {
this.repository = repository;
this.accessPolicy = accessPolicy;
this.exportClient = exportClient;
}
public ExportResult export(long reportId, User user) {
Report report = repository.findById(reportId)
.orElseThrow(ReportNotFound::new);
accessPolicy.checkExport(user, report);
return exportClient.export(ReportPayload.from(report));
}
}Клиент знает один use case export, а facade координирует внутренние collaborators.
Что остаётся снаружи
Facade не обязан закрывать низкоуровневый API для специальных сценариев. Он добавляет удобную границу, но не превращает подсистему в монолитный «главный сервис».
Хороший facade:
- говорит языком use case;
- не возвращает внутренние mutable objects;
- определяет error contract;
- не содержит случайный набор несвязанных методов;
- тестируется через наблюдаемый результат.
Цена
- появляется ещё один слой вызова;
- чрезмерный facade становится God Object;
- подсистема может протекать наружу через исключения и типы;
- транзакционная граница должна быть определена явно;
- удалённые вызовы внутри фасада не становятся атомарными вместе с БД.
Отличия
- Адаптер Adapter меняет несовместимый interface;
- Декоратор Decorator сохраняет interface и добавляет обязанность;
- Заместитель Proxy сохраняет interface и контролирует доступ;
- Facade создаёт более удобный высокоуровневый interface для подсистемы.
Вопросы для собеседования
- Обязан ли facade скрыть все классы подсистемы? Нет.
- Может ли facade быть application service? Да, если выражает use case и координирует зависимости.
- Главный риск? Собрать в одном классе все несвязанные операции системы.
- Чем отличается от Adapter? Facade упрощает доступ, Adapter согласует два контракта.