EnumBookFinder의 Switch문 방식 로직 리팩토링

태량·2023년 7월 13일
0

기존의 도서를 검색을 할 때 최적화된 검색 전략에 따라 전달 받은 TitleQuery를 통해 각각 정해진 SQL 쿼리문을 switch 문을 통해 분기하여 선택하는 방식이였다. 하지만 이 방식은 TitleQuery가 추가되거나 수정이 되면 이 메소드의 로직 또한 변경이 필요 한 점, switch 문이 포함하는 로직을 재사용 할 수 없다는 문제등이 있다. 실제로 추천 로직에서도 같은 형태의 switch문이 중복되서 사용되고 있다. 따라서 이러한 문제를 인식하고 리팩토링을 실시 한다.

[기존의 코드]

private Page<Book> selectBooksEntity(@NonNull TitleQuery titleQuery, Pageable pageable) {

        TitleType type = titleQuery.getTitleType();

        switch (type) {

            case KOR_SG, KOR_MT_OVER_TWO -> {
                return bookRepository.findBooksByKorNatural(titleQuery.getKorToken(), pageable);
            }

            case KOR_MT_TWO -> {
                return bookRepository.findBooksByKorMtFlexible(titleQuery.getKorToken(), pageable);
            }

            case ENG_SG -> {
                return bookRepository.findBooksByEngBool(titleQuery.getEngToken(), pageable);
            }

            case ENG_MT -> {
                return bookRepository.findBooksByEngMtFlexible(titleQuery.getEngToken(), pageable);
            }

            case ENG_KOR_SG -> {
                return bookRepository.findBooksByEngKorBool(titleQuery.getEngToken(),
                    titleQuery.getKorToken(), pageable);
            }

            case ENG_KOR_MT -> {
                return bookRepository.findBooksByEngKorNatural(
                    titleQuery.getEngToken(),
                    titleQuery.getKorToken(),
                    pageable);
            }

            default -> throw new IllegalArgumentException("Invalid title type: " + type);
        }
    }

switch문으로 분기 되어 선택 되던 로직을 각각의 전략으로 나누었다.

@RequiredArgsConstructor
@Component
public class EngNaturalSt implements SelectStrategy {

    private final BookRepository bookRepository;

    @Override
    public Page<Book> select(TitleQuery titleQuery, Pageable pageable) {
        return bookRepository.findBooksByEngNatural(titleQuery.getEngToken(), pageable);
    }
}
@Service
public class BookFinderImpl implements BookFinder<Page<BookDto>, Pageable>{

    private final Map<TitleType,SelectStrategy> strategyMap;

    public BookFinderImpl(BookRepository bookRepository) {
        this.strategyMap = new EnumMap<>(TitleType.class);

        strategyMap.put(KOR_SG, new KorNaturalSt(bookRepository));
        strategyMap.put(KOR_MT_OVER_TWO, new KorNaturalSt(bookRepository));
        strategyMap.put(KOR_MT_TWO, new KorBoolSt(bookRepository));
        strategyMap.put(ENG_SG,new EngBoolSt(bookRepository));
        strategyMap.put(ENG_MT,new EngBoolSt(bookRepository));
        strategyMap.put(ENG_KOR_SG, new EngKorBoolSt(bookRepository));
        strategyMap.put(ENG_KOR_MT, new EngKorNaturalSt(bookRepository));
    }

    @Override
    public Page<BookDto> findBooks(TitleQuery titleQuery, Pageable target) {

        TitleType type = titleQuery.getTitleType();

        SelectStrategy strategy = strategyMap.get(type);

        if(strategy == null){
            throw new IllegalArgumentException("Invalid title type: " + type);
        }

        return strategy.select(titleQuery,target).map(BookDto::new);
    }
}

그러고 나서 Switch문으로 분기되던 EnumBookFinder 대신 전략을 map 형태로 가지고 있으며, 생성자에서 map에 저장 한 뒤, 매개 변수로 들어오는 titleQuery안에 담겨진 TityeType의 형태에 따라서 Data JPA 메소드를 선택하게 했다.

profile
좋은 영향력과 교류를 위하여

0개의 댓글