다른 Feature가 NotificationConfigImplService의 기능을 필요로 할 경우
헥사고날 아키텍처의 원칙과 MSA를 고려했을 때, 다른 Feature가 NotificationConfigImplService
의 기능을 필요로 할 경우 아래 두 가지 접근 방식 중 하나를 선택할 수 있습니다.
1. 다른 Feature에 Port를 작성하고, NotificationConfigImplService
가 그것을 구현
설명:
다른 Feature에서 Port 인터페이스를 정의하고,
NotificationConfigImplService
가 해당 Port를 구현하도록 확장합니다.이렇게 하면 기존 Adapter(
NotificationConfigImplService
)를 재사용할 수 있습니다.
장점:
유지보수성:
Port를 통한 통신으로 Feature 간 의존성을 낮출 수 있습니다.
재사용성:
기존 구현체를 확장하여 중복 구현을 방지.
일관성:
헥사고날 아키텍처의 원칙(Port-Adapter)을 준수.
단점:
복잡성 증가:
NotificationConfigImplService
가 여러 Port를 구현하면 책임이 많아져 복잡해질 수 있음.
예시:
다른 Feature에 새로운 Port 정의
public interface AnotherFeaturePort {
NotificationConfig getConfigById(Long id);
}
기존 NotificationConfigImplService
가 Port를 구현
@Service
public class NotificationConfigImplService implements NotificationConfigService, AnotherFeaturePort {
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);
}
}
2. 새로운 Adapter를 작성
설명:
기존 Adapter(
NotificationConfigImplService
)를 참조하거나 위임하는 새로운 Adapter를 작성합니다.기존 Adapter는 변경하지 않고, 새로운 Feature의 요구사항에 맞는 Adapter를 별도로 작성합니다.
장점:
책임 분리:
새로운 Adapter는 특정 Feature의 요구사항만 처리하므로 책임이 분명해짐.
유연성:
기존
NotificationConfigImplService
에 의존하지 않고, 새로운 Adapter에서 Feature별 로직을 독립적으로 작성 가능.
변경의 영향 최소화:
기존 구현체를 변경하지 않아, 다른 Feature에 영향을 주지 않음.
단점:
중복 가능성:
기존 Adapter와 유사한 로직이 중복될 가능성.
관리 복잡성:
Adapter가 많아지면 관리가 복잡해질 수 있음.
예시:
새로운 Adapter 작성
@Service
public class AnotherFeatureAdapter {
private final NotificationConfigService notificationConfigService;
public AnotherFeatureAdapter(NotificationConfigService notificationConfigService) {
this.notificationConfigService = notificationConfigService;
}
public NotificationConfig getConfigById(Long id) {
return notificationConfigService.getConfigById(id);
}
}
어떤 접근이 더 적합한가?
1. Port 확장 방식 (기존 Adapter 확장):
적합한 경우:
새로운 Feature의 요구사항이 기존 Adapter의 기능과 밀접하게 관련된 경우.
기존 기능을 그대로 사용하거나 약간만 확장하는 경우.
비추천 사례:
새로운 Feature의 요구사항이 기존 Adapter와 크게 다르거나 독립적인 경우.
기존 Adapter의 책임이 과도하게 커지는 경우.
2. 새로운 Adapter 작성 방식:
적합한 경우:
새로운 Feature가 기존 Adapter와 독립적인 로직이나 비즈니스 규칙을 추가로 필요로 하는 경우.
특정 Feature에 종속적인 로직을 분리하여 유지보수를 용이하게 하고 싶은 경우.
비추천 사례:
단순히 기존 기능을 호출하는 수준에서 중복된 Adapter를 작성하는 경우.
결론
요구사항이 간단하고 기존 로직과 강하게 연결되어 있다면: Port 확장 방식이 적합.
새로운 Feature가 독립적인 로직을 포함하거나 확장이 크다면: 새로운 Adapter 작성 방식이 더 적합.
추천
먼저 요구사항의 복잡성과 연관성을 평가.
기존 Adapter에 영향을 주지 않으면서 최대한 재사용할 수 있는 방향으로 설계.