[리팩토링] ILikeYou 프로젝트 스프링 이벤트, pub/sub구조 적용 (의존성 줄이기)

2023. 8. 2. 18:46spring

기능을 추가하다 보니, service 에서 다른 service와 결합도가 너무 높아졌다.

 

그리고 서비스 계층이 수행하는 일이 너무 많아져서 코드가 복잡해져서 가독성도 좋지 않았다.

 

그래서 코드를 기능(행위)에 따라 분리하기 위해서 찾아보다가 스프링 이벤트라는 것을 발견했다.

 

동작 원리는 위 그림과 같다.


pub/sub 구조는 3가지로 분류된다.

 

1. 이벤트 객체(ApplicationEvent) 

//이벤트 처리에 필요한 내용을 담고 있음
@Getter
public class EventLiked extends ApplicationEvent {
    private LikeablePerson likeablePerson;
    public EventLiked(Object source, LikeablePerson likeablePerson) {
        super(source);
        this.likeablePerson = likeablePerson;
    }
}

 

2. 이벤트 발행자 (ApplicationPublisher)

//빈에 등록
private final ApplicationEventPublisher applicationEventPublisher;
//발생 이벤트와 이벤트 처리에 필요한 데이터 전달
applicationEventPublisher.publishEvent(new EventLiked(this, likeablePerson));

 

3. 이벤트 구독자 (@EventListener)

//구독할 이벤트 정의
//이벤트 처리
@Component
@RequiredArgsConstructor
public class InstaMemberEventListener {

    private final InstaMemberService instaMemberService;

    @EventListener
    public void listen(EventCanceledLike event) {
        instaMemberService.eventCanceledLike(event.getLikeablePerson());
    }

    @EventListener
    public void listen(EventLiked event) {
        instaMemberService.eventLiked(event.getLikeablePerson());
    }

모든 이벤트를 pub/sub 구조로 바꾸면 오히려 응집도가 떨어져서 비효율적이라고 생각했기 때문에 코드의 복잡성을 높이는 주요 이벤트에만 적용했다. 

이처럼 이벤트 처리할 기능을 선정해서 스프링이 Event를 발생시키도록 했다.

 

그리고 해당 이벤트를 처리할 도메인에서는 eventListener로 이벤트를 구독하도록 했다.

 

이로 인해 핵심 로직만 서비스에서 수행하게끔 하고, 이벤트가 발생했을 때 처리해야하는 부가적인 코드들은 Listener 를 통해서 처리할 수 있게 구현했다.

 

이로 인해 하나의 Service 클래스(LikeableService) 안에 코드가 계속적으로 증가하는 문제를 해결할 수 있었다.

 

참고링크

https://findstar.pe.kr/2022/09/17/points-to-consider-when-using-the-Spring-Events-feature/