/
NotificationConfigRepository 에 대해서 NotificationConfigService는 Outbound port 이고 NotificationConfigImplService는 그에 대한 adapter라고 볼수 있나?

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]

 

  1. Core Domain:

    • 핵심 비즈니스 로직에서는 NotificationConfigService(Outbound Port)에만 의존합니다.

    • 이를 통해 비즈니스 로직은 영속성 세부 사항과 무관하게 유지됩니다.

  2. Outbound Port:

    • NotificationConfigService는 데이터베이스와의 상호작용에 필요한 기능을 정의합니다.

    • 인터페이스이므로 구현 세부 사항에 의존하지 않습니다.

  3. Adapter:

    • NotificationConfigImplService는 Port의 구현체로서 실제 데이터 처리 로직을 포함합니다.

    • 이 구현체는 데이터베이스에 접근하기 위해 내부적으로 NotificationConfigRepository를 호출합니다.

  4. 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

 


이 구조의 장점

  1. 유연성: Port(인터페이스)와 Adapter(구현체)를 분리하여 구현 변경 시에도 Core Domain에 영향을 주지 않음.

  2. 테스트 용이성: Port 인터페이스를 Mocking하여 Core Domain의 테스트를 독립적으로 수행 가능.

  3. 확장성: 다른 Adapter(예: 외부 API와의 통신)를 추가하거나, 데이터 저장소를 변경(MySQL → MongoDB)하는 작업이 용이.