NotificationConfigRepository 에 대해서 NotificationConfigService는 Outbound port 이고 NotificationConfigImplService는 그에 대한 adapter라고 볼수 있나?
헥사고날 아키텍처에서 NotificationConfigService
를 Outbound Port로, NotificationConfigImplService
를 그 Port의 Adapter로 보는 관점과 일치합니다. 이를 좀 더 구체적으로 살펴보겠습니다.
구조 분석
1. NotificationConfigRepository
역할:
JPA와 같은 영속성 프레임워크를 사용하여
NotificationConfig
데이터를 데이터베이스와 상호작용하는 실제 구현체입니다.헥사고날 아키텍처에서는
Infrastructure
계층에 속합니다.
2. NotificationConfigService
역할:
Outbound Port로서 정의된 인터페이스입니다.
애플리케이션의 핵심 비즈니스 로직에서 외부 시스템(데이터베이스)과 통신해야 할 때 의존하는 추상화 계층입니다.
인터페이스만 제공하며, 구체적인 구현은 Adapter에서 담당합니다.
3. NotificationConfigImplService
역할:
Adapter로서
NotificationConfigService
인터페이스를 구현합니다.구체적인 구현체로, 내부적으로
NotificationConfigRepository
를 호출하여 데이터를 처리하거나 저장합니다.
헥사고날 아키텍처에서의 매핑
[Core Domain]
|
|---> [Outbound Port: NotificationConfigService]
|
|---> [Adapter: NotificationConfigImplService]
|
|---> [Repository: NotificationConfigRepository]
Core Domain:
핵심 비즈니스 로직에서는
NotificationConfigService
(Outbound Port)에만 의존합니다.이를 통해 비즈니스 로직은 영속성 세부 사항과 무관하게 유지됩니다.
Outbound Port:
NotificationConfigService
는 데이터베이스와의 상호작용에 필요한 기능을 정의합니다.인터페이스이므로 구현 세부 사항에 의존하지 않습니다.
Adapter:
NotificationConfigImplService
는 Port의 구현체로서 실제 데이터 처리 로직을 포함합니다.이 구현체는 데이터베이스에 접근하기 위해 내부적으로
NotificationConfigRepository
를 호출합니다.
Repository:
JPA 기반으로 데이터베이스에 저장하거나 가져오는 작업을 수행합니다.
코드 예시
1. Outbound Port
public interface NotificationConfigService {
NotificationConfig getConfigById(Long id);
NotificationConfig saveConfig(NotificationConfig config);
}
2. Adapter (구현체)
@Service
public class NotificationConfigImplService implements NotificationConfigService {
private final NotificationConfigRepository repository;
public NotificationConfigImplService(NotificationConfigRepository repository) {
this.repository = repository;
}
@Override
public NotificationConfig getConfigById(Long id) {
return repository.findById(id)
.orElseThrow(() -> new RuntimeException("Config not found"));
}
@Override
public NotificationConfig saveConfig(NotificationConfig config) {
return repository.save(config);
}
}
3. Repository
이 구조의 장점
유연성: Port(인터페이스)와 Adapter(구현체)를 분리하여 구현 변경 시에도 Core Domain에 영향을 주지 않음.
테스트 용이성: Port 인터페이스를 Mocking하여 Core Domain의 테스트를 독립적으로 수행 가능.
확장성: 다른 Adapter(예: 외부 API와의 통신)를 추가하거나, 데이터 저장소를 변경(MySQL → MongoDB)하는 작업이 용이.