Ответ
Repository и Facade — это структурные паттерны, но они решают принципиально разные задачи.
Паттерн Repository
Назначение: Инкапсулирует логику доступа к данным, выступая в роли абстракции над хранилищем (БД, внешний API, файловая система). Он отделяет бизнес-логику от деталей работы с источниками данных.
Пример на C#:
// Абстракция репозитория
public interface IUserRepository
{
User GetById(int id);
void Add(User user);
IEnumerable<User> Find(Expression<Func<User, bool>> predicate);
}
// Конкретная реализация
public class SqlUserRepository : IUserRepository
{
private readonly AppDbContext _context;
public SqlUserRepository(AppDbContext context) => _context = context;
public User GetById(int id)
{
// Детали доступа к БД скрыты здесь
return _context.Users.FirstOrDefault(u => u.Id == id);
}
// ... другие методы
}
Почему используется: Позволяет легко подменять источник данных (например, для тестов использовать InMemory-репозиторий) и централизует запросы (например, спецификации).
Паттерн Facade
Назначение: Предоставляет простой, унифицированный интерфейс к сложной подсистеме, скрывая её внутренние зависимости и сложность.
Пример на C#:
// Сложная подсистема
public class PaymentService { public void Process(Payment p) { /* ... */ } }
public class InventoryService { public void Reserve(Order o) { /* ... */ } }
public class NotificationService { public void SendReceipt(Order o) { /* ... */ } }
// Фасад, упрощающий взаимодействие
public class OrderProcessingFacade
{
private readonly PaymentService _payment;
private readonly InventoryService _inventory;
private readonly NotificationService _notification;
public OrderProcessingFacade(PaymentService p, InventoryService i, NotificationService n)
{
_payment = p; _inventory = i; _notification = n;
}
public bool PlaceOrder(Order order)
{
// Клиент вызывает один метод вместо трёх
_inventory.Reserve(order);
_payment.Process(order.Payment);
_notification.SendReceipt(order);
return true;
}
}
Почему используется: Уменьшает связность клиентского кода с подсистемой, делает код чище и проще для использования.
Ключевые отличия
| Аспект | Repository | Facade |
|---|---|---|
| Предмет работы | Данные (сущности, агрегаты). | Действия и операции сложной подсистемы. |
| Основная цель | Абстракция над источником данных. | Упрощение интерфейса к набору классов. |
| Типичный результат | Возвращает доменные объекты или коллекции. | Часто выполняет операцию без возврата значения или возвращает упрощённый результат. |
| Уровень применения | Уровень доступа к данным (DAL). | Уровень координации сервисов или модулей. |