event를 이용한 의존성 제거 1

Hyuk·2023년 9월 4일
0

HappyScrolls 개발기

목록 보기
12/24
post-thumbnail

event를 이용한 의존성 제거 2
에서 이번 글에서 작성한 코드의 문제점을 찾고 보완합니다.

이벤트를 이용해서 의존성을 제거하고, 언제 쓰는것이 적절한지 고민해보았다.

한 서비스레이어 코드에 의존성이 너무 많이 얽혀있고, 이를 완화하고 싶어서 이것저것 찾아봤다.

    public List<Buy> buyCreate(Member member, BuyDTO.RequestCart request) {

        List<Buy> response = new ArrayList<>();

		중략...
		
        -------제거될 부분 (의존성이 복잡하다고 판단된 부분)
        |
        |
		cartService.deleteCarts(cartList);
		memberService.decreasePoint(member,requirePoints); 
        notificationService.notiBuy(response);
        |
        |
        -------제거될 부분

        return response;
    }

일단 코드가 길다. 장바구니의 물건을을 구매하는 코드이다.

그리고 이 클래스는 다른 세개의 서비스를 의존히고 있다.

public class BuyService {

    @Autowired
    private BuyRepository buyRepository;

    @Autowired
    private CartService cartService;

    @Autowired
    private ProductService productService;
    
    @Autowired
    private MemberService memberService;
    
    @Autowired
    private NotificationService notificationService;
    
    예상 의존성 추가 지점

만약 buyCreate가 일어난 후, 쿠폰을 발행해준다거나, 레벨을 높여주는 등의 다른 로직이 추가된다면 기존 메소드에도 코드가 변경되고, 클래스의 의존성에도 변경이 된다.

또한 BuyService코드에 변경이 지속적으로 생기고 이는 OCP를 위반하게 된다.

한 서비스 레이어에서 다른 서비스레이어를 의존하는 것이 꼭 문제는 아니지만. 이렇게 많은 서비스를 의존하게 된다면 기존 서비스 레이어메소드들의 역할이 모호해질 수 있고, 여기 뿐만 아니라다른 곳에서도 의존성이 꼬일 수 있다.

따라서 이벤트를 사용하기로 했다.
기존에 다른 서비스를 호출하는 부분 ( 구매시 멤버 포인트 감소, 구매시 장바구니 항목을 삭제하는 부분, 알림을 생성하는 부분) 들은 이벤트를 이용하므로 더이상 BuyService에서 모습을 찾아볼 수 없다.

바뀐 부분

   public List<Buy> buyCreate(Member member, BuyDTO.RequestCart request) {

        List<Buy> response = new ArrayList<>();

		중략...
		
		바뀐 부분(기존 코드 삭제됨)
        applicationEventPublisher.publishEvent(new BuyEvent(member,requirePoints,cartList));


        return response;
    }

이벤트리스너


@EventListener
    public void cartDelete(BuyEvent event) {
        for (Cart cart : event.getCartList()) {
            cartRepository.delete(cart);
        }
    }
    
    @EventListener
    public void pointDecrease(BuyEvent event) {
        Member member = event.getMember();
        Integer requirePoints = event.getPrice();
        member.decreasePoint(requirePoints);
        memberRepository.save(member);
    }
    
    @EventListener
    public void notiBuy(BuyEvent event) {
        Member member = event.getMember();
        for (Cart cart : event.getCartList()) {
        	Notifacation noti=Notifacation.builder()
            							  .member(member)
                                          .msg("물건 구매")
                                          .refId(cart.getProduct().getId())
                                          .build();
            notificationRepository.save(noti);
        }
    }

이벤트로 의존성을 완화한 덕분에 후에 알림을 날리는 기능이 생기더라도, BuyService에 코드가 추가되지 않아도 된다.

🤔문제는 없을까?

다만 문제는 이벤트 리스너가 여기저기 퍼져있다보니, 기능을 한 눈에 파악하기 힘들다는 단점이 새로 생겼다.

profile
🙂 🙃 🙂 🙃

0개의 댓글