Ответ
Шестигранная архитектура (Ports & Adapters) — это паттерн, который изолирует бизнес-логику (ядро) от внешних зависимостей (UI, БД, внешние сервисы) через абстракции (порты) и их реализации (адаптеры).
Ключевые компоненты:
- Ядро (Domain): Содержит бизнес-логику и сущности. Не зависит от внешнего мира.
- Порты (Ports): Интерфейсы, которые определяют, как ядро взаимодействует с внешним миром.
- Входные порты (Driving Ports): Для получения команд/запросов (например,
UserService). - Выходные порты (Driven Ports): Для доступа к данным или внешним сервисам (например,
UserRepository).
- Входные порты (Driving Ports): Для получения команд/запросов (например,
- Адаптеры (Adapters): Реализации портов, которые переводят запросы из внешнего мира в вызовы ядра и наоборот.
Пример структуры:
// ЯДРО (не зависит от фреймворков)
// Выходной порт (интерфейс, который определяет ядро)
public interface UserRepositoryPort {
User findById(Long id);
}
// Входной порт (сервис, реализующий бизнес-логику)
public class UserService {
private final UserRepositoryPort repository;
public UserService(UserRepositoryPort repository) {
this.repository = repository; // Dependency Injection
}
public User getUser(Long id) {
// Бизнес-логика (например, валидация)
return repository.findById(id);
}
}
// АДАПТЕР ВНЕШНЕГО МИРА (зависит от фреймворка, например, Spring Data JPA)
@Component
public class JpaUserRepositoryAdapter implements UserRepositoryPort {
@Override
public User findById(Long id) {
// Реализация с использованием JPA (Spring Data)
return jpaRepository.findById(id).orElse(null);
}
}
Преимущества:
- Тестируемость: Ядро можно тестировать в изоляции с помощью мок-адаптеров.
- Гибкость: Замена базы данных или UI требует изменения только адаптера, а не бизнес-логики.
- Сохранность бизнес-правил: Ядро защищено от изменений во внешних фреймворках.
Недостатки:
- Сложность: Увеличивает количество слоев и boilerplate-кода.
- Избыточность: Может быть неподходящей для простых CRUD-приложений.