공부/Spring

Facade 패턴과 Factory 패턴

minho-bot 2024. 11. 10. 15:38

코드를 짜다보면 클래스가 많아진다.

클래스가 많아지면서 코드가 복잡해지고 중복되는 부분도 자주 생길 수 있다.

이런 경우에 쓸 수 있는 디자인 패턴 2가지를 알아보자.

Controller, Service, Repository 를 사용하는 Spring mvc 를 기준으로 설명하겠다.

 

Facade 패턴과 Factory 패턴 모두 Controller 와 Service 사이에 컴포넌트가 추가된다.

각 패턴의 예시를 보여주고 장점? 의의? 를 내가 느끼는 대로 추가로 설명하겠다.


Facade 패턴

한 컨트롤러에서 여러 서비스를 호출하면서 호출하는 클래스가 많아져 코드가 복잡해질 때 사용할 수 있다.

 

예를 들어 물건을 사려면
1. MemberService 에서 사용자를 검색한 후

2. ItemServie 에서 아이템 id 로 아이템을 가져와 재고 수를 줄이고 가격을 확인 후

3. PaymentService 에서 결제를 진행 후

4. DeliveryService 에서 배송을 등록 하면

물건을 사게 된다.

 

이렇게 OrderController 에서 여러 서비스를 호출 하는 게 보기 싫을 수 있다.

그런데 이 서비스들이 서로 맞물려서 돌아가야하는 로직이 구매 말고도 있을 수 있다.

예를 들어 환불 로직에서도 같은 서비스들을 써야할 것이다.

사용자 검색하고, 재고도 올리고, 결제, 배송되 취소해야한다.

 

이런 복잡한 코드를 줄이기 위해 Controller 와 4개의 Service 들 사이에 OrderFacade 를 두면 코드가 좀 더 깔끔해질 수 있다.

OrderController - OrderFacade - (Member, Item, Payment, Delivery) Service

 

어차피 여러 서비스들을 호출해야하는데 그걸 Controller 에서 하는게 아니라 Facade 를 만들어서 역할을 분리하는데에 의미가 있는 것 같다.

 


Factory 패턴

비슷한 기능의 서비스들 상위에 인터페이스를 만들어서 공통화 하고싶을 때 쓸 수 있다.

 

예를 들어 초등학생, 중학생, 고등학생에 대한 통계를 낼 때

ElementarySchoolStatisticsService, MiddleSchoolStatisticsService, HighSchoolStatisticsService 가 있을 것이다.

 

만약에 공부시간, 수면시간, 노는시간 에 대한 통계를 낸다면

이 서비스들의 input 과 output 으로 쓰이는 dto 가 공부시간, 수면시간, 노는시간으로 비슷할 것이다. TimeDto 라고 하자

이 3개의 서비스 상위에 SchoolStatisticsFactory 인터페이스를 만들고 공통 각 서비스에서 TimeDto 를 반환하는 함수를 구현한다.

 

이제 SchoolType enum class 를 만들어서

Map<SchoolType, SchoolStatisticsFactory> 맵을 만든 후 꺼내서 사용하면 된다.

 

어차피 서비스 3개의 내부 로직이 다를 수 있어서 따로 구현을 해야하지만 초등학생, 중학생, 고등학생 에 대한 분기처리를 if else 로 하는 것 보다 map 으로 깔끔하게 할 수 있다. 이후에 공통화 된 함수를 호출하여 구현에 대한 코드를 신경쓰지 않을 수 있다.