ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Service에서 Service를 참조해야만하나? (with Facade 패턴)
    실전 개발해보기 2024. 2. 4. 11:26

     

    순환 참조

     

    이번 팀플을 해볼 때

    내 도메인을 다른 도메인(팀원이)에서 가져다 쓸 것을 크게 고려하지 않고, 

    내 도메인에 대한 기능만 충실하면 된다고 착각해서,

     

    Presentation(Controller)

                  |

           Application(Service)

                  |

           (Domain)

                  |

    Infrastructure(Repository) 

     

    구조로 짰다.

     

    쿠폰은 내가 다른 Service 을 가져다 쓸 부분은 없고 도메인 과 레포지토리 정도였다.

    그러나 다른 도메인의  Service에서는 Coupon에 대한 기능이  필요했다. 

     

    다 짜고 보니까 다른 ProductService에서 CouponService 에 있는 기능이 필요했다.

     

    그래서 몇가지 해결법을 정리해보았는데, 해결법중 뭐가 정답이다! 라는건 없다고 생각한다.

    각 방법끼리의 트레이드 오프가 있고

    현재 프로젝트에서 최적의 방법을 찾아가면 되는 것이다 !!

     


    해결법 1

     

    가장 단순한 방법으로 Service영역에서 Service 의존성을 받아서 사용할 수 있다.

     

    MemberService 에 a() 메서드가 있고

    TeamService에 a()메서드가 있을때,

     

    트레이드 오프 1

     

    Team의 a와 Member의 a 메서드를 하나의 트랜잭션으로 실행시키고 싶은 경우에는 

    결국 각각 작동하기 때문에 트랜잭션의 원자성(Atomicity)을 지키지 못한다. 

     

    물론 조회만 필요한 경우에는 위는 문제 삼지 않는다.

     

    트레이드 오프 2

     

    특정 서비스를 의존한다는것은 그 해당 서비스의 메서드를 사용하기 위해 가져오는 것인데,

    이 때 의존하는 서비스가 내가 필요한 부분 외에 수많은 기능이 있다면, 

    필요 이상의 기능(의존하려는 Service)에 의존한다고 볼 수 있다.

     

    또한 의존하는 서비스가 크면 클수록 순환 참조에 대한 문제도 조금 더 고려해봐야한다.


     

    해결법 2

     

    그럼 ProductController에서 여러 Service를 의존하고, 여러 Service에 대한 기능을 받아서 합치면 되지 않을까? 라는 생각을 했다. 

     

    트레이드 오프 

     

    조회의 경우에는 트랜잭션이 딱히 필요없지만 

     

    여러 로직(삽입+조회)을 수행해야 하는 경우에는 트랜잭션이 필수인데,

    컨트롤러에서는 일반적으로 거는 트랜잭션 범위(service계층)를 벗어나기에 로직들을 하나로 묶을 수 없다.

     

     

    참고로 트랜잭션이 필요하지 않은 경우에는 많진 않지만..

    Service를 아예 사용하지 않고 Controller -> Repository를 불러오는 경우도 있다고 한다.

     

     


     

    해결법 3

     

    Facade 패턴 이용하기

     

    찾아보니 스프링에서도 Service의 역할을  Business service facade라고 부르기도 하고있다.

     

    스프링에서 Facade 패턴은 새로운 계층을 만든다는  의미보다 Service를  더 촘촘히 나눠서 구현하는 것이라 볼 수 있다.

     

    Service 레이어에서 그대로 다른 도메인 Service를 의존하지 않고

    조금은 다른  Service에 의존하는 것이라고 생각하면 된다.

     

     


     

    나는 하나의 Service 가 너무 커지는 것 같아서,

     

    1. Service를 다른 도메인에서 가져다 쓰는 것에 따라 분리를 하고,

    2. Facade 패턴을 이용해서 해당 문제를 해결했다.

     


     

    Reference

     

    - https://www.inflearn.com/questions/987690/%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A0%88%EC%9D%B4%EC%96%B4-%EB%81%BC%EB%A6%AC%EC%9D%98-%EC%9D%98%EC%A1%B4

    - https://www.inflearn.com/questions/30618/%EA%B6%81%EA%B8%88%ED%95%A9%EB%8B%88%EB%8B%A4

Designed by Tistory.