JustDoEat
상품검색 서비스가 언제 확장될지 모른다! 전략패턴(Strategy Pattern)으로 해결해보자 본문
개요.
상품 검색 기능을 리팩터링 하는 중, 의문이 생김..
일단! 제목으로 검색만 만들고(지금까지는 이렇게 하기로 함.)
나중에 태그별, 위치별로 상품을 검색하는 기능을 만들려고 하는데(추후 고도화 때나 할거 같음)
처음에는 단순하게
if문을 써서, "제목별", "태그별", "위치별" 단어를 구분해서 거기에 맞는 서비스를 호출하려고 했는데..
검색 관련 로직이 추가되거나 영역이 확장된다면 그만큼 if문도 늘어나고 아무리 봐도 더 좋은 방법이 있지 않을까 해서 찾아보다 발견했다.
대충 어떤 느낌이었냐면
일단, 우테코 프리코스 찍먹을 하면서 if-else문은 가독성을 떨어뜨리므로 가급적 삼가야 한다고 들었다. 그럼 조건에 따라 서비스를 주입하고 싶다...라는 생각? 에서 나온 기가 막힌 방법!!
그것은 전략패턴 Strategy Pattern이다. 이론적인 정형적인 정리는 하지 않고 맨 뒤에 내 생각을 적어보겠다!!
1. 전략패턴 인터페이스를 정의해 준다, 나는 검색에 관한 게 필요하므로, search라는 메서드만 정의를 해주었다
- 동일한 문제에 대한 다양한 전략들을 하나의 인터페이스로 통합 관리하기 위해 필요하다.
- 동일한 문제(Search)에 대란 다양한 전략(태그별 검색, 제목별 검색, 그 외 확장될 부분까지)들을 ProductSearchStrategy 인터페이스로 관리
2. 인터페이스를 만들었다면? 구현체를 만들어 준다, 현제는 "태그", "제목" 이 두 가지가 필요하기에 두 개만 구현하였다.
(아 이 부분은... 아직 미완성이다, 검색 메서드 안에 리스트 변환, null 추가 등 불필요한 로직이 있는데 추후에 리펙터링 하면서 단일책임의 원칙을 준수하도록 할 것이다!)
3. 전략패턴을 사용하기 위한 콘텍스트 클래스 작성.
- 콘텍스트 클래스는 전략 클래스 중에서 현재 조건에 맞는 전략을 선택하여 실행하는 역할을 한다!
- 즉, 조건에 따라 전략을 선택하고 실행하는 책임을 가진다. 직접적으로 알고리즘을 구현하지 않고, 현재 조건에 맞는 전략클래스에게 구현을 위임한다.
"그래서 동작이 어떤 식으로 되는 건데요....!!"
- Service 어노테이션 옆에 적은 값은 전략을 구분하기 위한 Key 값이 된다
- Service 어노테이션 옆에 적은 값이 없다면 productSearchByTitleStrategy, productSearchByTagStrategy가 키 값이 된다.
=> 어노테이션에 값이 없으면, 스프링은 기본적으로 클래스 이름을 Key로 사용함.
스프링이 올라가면서 의존성 주입이 될 때
위에 보이는, Map <string, productsearchstrategy>을 이용하여 각 전략을 Key-Value 형태로 주입한다.
Map <"제목", ProductSearchByTitleStrategy>
Map <"태그", ProductSearchByTagStrategy>
콘텍스트 클래스가 실행이 되면서
나의 경우에는 detail의 값에 따라 다양한 전략들이 실행되도록 흐름제어를 하였다.
예를 들어, detail 값에
"제목" 이 들어가면 ProductSearchByTitleStrategy
"태그"가 들어가면 ProductSearchByTagStrategy
전략패턴에 대해 좀 더(내 생각)
나의 상황에 빗대어 보면, 클라이언트가 "태그"라는 종이를 들고 있다면, 태그를 이용 한 검색을 해야 할 것이고.
"제목"이라는 종이를 들고 온다면 제목을 이용한 검색을 해야 할 것이다.
어떤 검색조건을 가지고 오든 명령은 정해져 있다 그건 바로 Search라는 검색.
내가 내릴 수 있는 공통적인 명령(. Search())의 껍데기를 인터페이스로 지정을 했고, 인터페이스의 구현체로 각 명령에 대해 취해야 하는 행동을 지정했다.
그 독집적인 행동을 콘텍스트에서 갈아 끼우게 했다!!
내가 전략패턴을 쓴 이유는, 검색 전략에 따라 유효성 검사, 검색에 따른 추가 로직이 전략마다 조금씩 다를 거 같아 한 서비스에 몰아넣고 조건에 따라 쓰기보다는, 명령에 기반해서 전략을 세팅해 주는 방식이 좋을 거 같아서 적용을 해 보았다!
'Yajoba > Backend' 카테고리의 다른 글
[SpringMVC,문제해결] 멀티파트 요청에서 File 타입, DTO 바인딩 문제 ModelAttribute와 RequestPart 차이에서 오는 문제 (0) | 2024.11.30 |
---|---|
MultipartFile 에서 파일 확장자를 검사 해보자. + 멀티파트에서 @Validated가 안되는 현상 (4) | 2024.11.28 |
팩토리 클래스에 객체 생성에 필요한 서비스를 의존을 받았다. 정답일까 아닐까 (1) | 2024.11.21 |
Data JPA, DTO, Projection 방식중 적합 한 방식은 ? (0) | 2024.10.28 |
[문제해결]카테고리입니다, 셀프조인도 같이 드시면 맛있습니다 (4) | 2024.10.13 |