ecsimsw

도메인 이벤트를 이용하여 의존성 분리 연습 본문

도메인 이벤트를 이용하여 의존성 분리 연습

JinHwan Kim 2022. 1. 12. 14:16

도메인 이벤트로 의존성 분리?

우아한테크코스 지원 플랫폼 개발을 하면서 제이슨한테 배운 개념이다. 그 당시에는 '오 멋진걸~, 이렇게도 할 수 있구나 🤩' 정도였도로 지나쳤었다. 패키지간의 의존, 리팩토링을 위한 분리를 고민하기 시작하면서 이제는 좀 더 와닿아서 이렇게 대박 기술인 양 정리하게 되었다.

 

문제와 요구 사항

커머스 서버를 만드는 프로젝트를 발전시키는 중이었다. 기존에는 없었던 명세였는데, 각 상품별 주문 횟수를 기록할 수 있다는 요구 사항이 추가되었다.

 

1. 사용자가 주문(Order)을 생성하게 되면, 그 장바구니에 포함된 각 제품(Product)에 orderedCount를 증가시킨다.

 

이 이전까지는 OrderService는 Product 관련 도메인을 분리해둔 상황이었다. 이번 요구 사항을 위해서 OrderService에 Product 관련 Repository 참고가, 더 크게 Order 패키지의 관점에서도 불필요했던 Product 패키지의 참조가 필요해졌다.

 

Product 코드 관련 로직이 추가되어 OrderService 코드가 복잡해지고, 관련 로직을 위한 테스트 코드를 작성하는데에도 더 많은 코드가 필요해졌다. OrderService와 테스트에서 집중해야 하는 주 역할이 아닌, Product에 관심이 뺏기고 있는 상황이었다.

 

이벤트로 Order과 Product를 분리해보자.

이런 상황안에서 Order과 Product를 분리하기 위해 이벤트 핸들링을 사용했다. OrderService에선 주문이 생성되는 이벤트를 발생시키고, 그 이후에 그 이벤트가 처리되는 과정은 관심 밖으로 하는 것이다.

 

1. 기존의 Product 관련 참조 객체들을 제거하고, ApplicationEventPublisher의 의존성을 주입받는다.

 

일단 불필요한 객체 참조가 빠진 것에 편안함을 느낄 수 있다.

 

 

2. 그리고 상품 생성 관련 이벤트를 정의 후 발행한다. 기존의 Product 관련 로직을 제거할 수 있다.

 

이전 : Product 관련 로직으로 Order의 메인 관심사에 집중 X

 

이후 : 이벤트를 발행하는 것으로 Product 관련 로직 제거

 

3. 발생한 이벤트를 처리할 listener를 정의하고, 제거했던 Product 관련 로직을 옮긴다.

 

이때 이벤트를 처리하는 로직은 비동기로 처리하였다. 사용자의 상품 주문 요청을 처리하는 시나리오 (주문 -> 이벤트 발행 -> 응답)과 별개의 스레드로 이벤트를 처리하고 싶었다. 굳이 그 이벤트가 처리 완료되기까지 기다릴 필요가 없는 상황이기 때문이다.

 

 

분리와 집중

이렇게 이벤트를 활용하여 OrderService에서 제품 관련 코드를 분리해보았다. 그 결과로 패키지간 참조가 줄었고, 테스트가 쉬워졌으며, 서비스 코드 안에서 집중해야 하는 로직에만 집중할 수 있게 되었다.

 

아마 나와 같이 이벤트를 던지고, 받는 방법만 알지 어디서 이걸 사용해야하는지 모르시는 학생 개발자분들이 많으시지 않을까 생각한다.

 

특히 멀티 모듈 고민이나 레거시 코드 리팩토링(클래스 파일 분리)을 고민 중이시라면 이번 글처럼 도메인 이벤트를 이용하는 것이 쉽고 효과적인 풀이 방향이 될 것이라고 생각한다.

Comments