실제 Legacy 환경의 현업에서 일한지 대략 1년 쯤 된 지금...
어느정도 기능의 측면에서 패키지 구조가 분리되어 있지만, 패키지 안에 단일 Controller, Service, Repository로 구성된 곳에서 일하다보니 일단 하나의 서비스 클래스 파일에서 소스가 3~40000줄은 기본으로 넘는다.
여기서 특정 기능의 추가나 디버깅, 혹은 메서드 수정을 할 때 A라는 도메인에서 쓰여야할 private한 메서드가 기능적으로 어느정도 비슷해서 B,C,D 와 같은 로직에서도 사용하고.. 뭐 하나를 고치려고 찾는 것 조차도 힘들다.
그리고 실제 필요한 기능이 있어서 구현했더니 , 나중가서 보니 23000번째 라인에서 구현이 되어있다던가...
- 여러 세부 서비스들을 한 번에 묶어서, 외부에서 보기에 단일한 인터페이스를 제공하는 것
- 이를 위해서는 각각의 순수 도메인에 관련하여 비즈니스 로직을 구현한 서비스가 존재해야함
=> 이를 이용해 특정 기능을 구현할 때 해당 도메인 서비스( "ModuleService" )들을 조합하여 사용!
ex. OrderFacadeService가 주문 + 결제 + 포인트를 함께 처리
즉 3개의 도메인의 협력이 필요할 때 해당 Facade에서 의존하고, 각각의 도메인 서비스는 순수하게 유지할 수 있음 (기존 단순 service + repo 구조는, 반드시 service끼리의 의존 혹은 service에서 필요한 repo에 의존을 걸어 데이터를 가져와야해서 경계가 무너짐) / @Transcation 흐름 묶기도 편함
예시코드 :
@Service
@RequiredArgsConstructor
public class OrderFacadeService {
private final OrderService orderService;
private final MemberService memberService;
private final PaymentService paymentService; //
//해당 Service들은 만약 다형성이 필요해 구현체를 갈아끼울 가능성이 있다면 interface
//그 외에는 구체 클래스로 구현하여 관리포인트 down
@Transactional
public OrderResultDto placeOrder(OrderRequestDto request) {
Member member = memberService.findById(request.getMemberId());
Order order = orderService.createOrder(member, request.getItems());
paymentService.pay(order);
return OrderResultDto.of(order);
}
}
