/
다른 Feature가 NotificationConfigImplService의 기능을 필요로 할 경우

다른 Feature가 NotificationConfigImplService의 기능을 필요로 할 경우

헥사고날 아키텍처의 원칙과 MSA를 고려했을 때, 다른 Feature가 NotificationConfigImplService의 기능을 필요로 할 경우 아래 두 가지 접근 방식 중 하나를 선택할 수 있습니다.


1. 다른 Feature에 Port를 작성하고, NotificationConfigImplService가 그것을 구현

설명:

  • 다른 Feature에서 Port 인터페이스를 정의하고, NotificationConfigImplService가 해당 Port를 구현하도록 확장합니다.

  • 이렇게 하면 기존 Adapter(NotificationConfigImplService)를 재사용할 수 있습니다.

장점:

  1. 유지보수성:

    • Port를 통한 통신으로 Feature 간 의존성을 낮출 수 있습니다.

  2. 재사용성:

    • 기존 구현체를 확장하여 중복 구현을 방지.

  3. 일관성:

    • 헥사고날 아키텍처의 원칙(Port-Adapter)을 준수.

단점:

  1. 복잡성 증가:

    • 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를 별도로 작성합니다.

장점:

  1. 책임 분리:

    • 새로운 Adapter는 특정 Feature의 요구사항만 처리하므로 책임이 분명해짐.

  2. 유연성:

    • 기존 NotificationConfigImplService에 의존하지 않고, 새로운 Adapter에서 Feature별 로직을 독립적으로 작성 가능.

  3. 변경의 영향 최소화:

    • 기존 구현체를 변경하지 않아, 다른 Feature에 영향을 주지 않음.

단점:

  1. 중복 가능성:

    • 기존 Adapter와 유사한 로직이 중복될 가능성.

  2. 관리 복잡성:

    • 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 작성 방식이 더 적합.

추천

  1. 먼저 요구사항의 복잡성과 연관성을 평가.

  2. 기존 Adapter에 영향을 주지 않으면서 최대한 재사용할 수 있는 방향으로 설계.