티스토리 뷰
Introduction
프로젝트를 하던 중, DB 에서 테이블을 조회하는 코드가 중복이 많다는 것을 알게 되었다. 이후 중복을 없애기 위해 디자인 패턴을 적용하자고 마음을 먹고 전략 패턴을 적용해보았다.
패턴 적용 전 코드
public SearchPageGetResponse<TrackGetResponse> findTracksWithKeyword(Pageable pageable, String searchKey, String memberEmail) {
Member member = validateMember(memberEmail);
Page<TrackGetResponse> tracks = trackRepository
.findAllByTrackTitleContainingOrAlbumAlbumTitleContainingOrArtistArtistNameContaining(keyword, keyword, keyword, pageable)
.map(trackPage -> trackPage.map(TrackGetResponse::of))
.orElseGet(() -> new PageImpl<>(Collections.emptyList()));
return tracks.isEmpty() ?
SearchPageGetResponse.of(message.substring(0,message.length()-1) + " 검색 결과가 없습니다.", pagedItems)
: SearchPageGetResponse.of(
String.format("'%s' 으로 총 %s개의 음원을 찾았습니다.",
searchKey,
tracks.getTotalElements()), tracks);
}
public SearchPageGetResponse<SearchMembersResponse> findMembersWithKeyword(Pageable pageable, String searchKey, String memberEmail) {
Member member = validateMember(memberEmail);
Page<SearchMembersResponse> members = memberRepository
.findByNickNameContaining(keyword, pageable)
.map(memberPage -> memberPage.map(SearchMembersResponse::of))
.orElseGet(() -> new PageImpl<>(Collections.emptyList()));
return members.isEmpty() ?
SearchPageGetResponse.of(message.substring(0,message.length()-1) + " 검색 결과가 없습니다.", pagedItems)
: SearchPageGetResponse.of(
String.format("'%s' 으로 총 %s개의 사용자를 찾았습니다.",
searchKey,
members.getTotalElements()), members);
}
public SearchPageGetResponse<SearchRecommendsResponse> findMembersWithKeyword(Pageable pageable, String searchKey, String memberEmail) {
Member member = validateMember(memberEmail);
Page<SearchRecommendsResponse> recommends =
recommendRepository.findByRecommendTitleContaining(keyword, pageable)
.map(recommendPage -> recommendPage.map(SearchRecommendRespons::of))
.orElseGet(() -> new PageImpl<>(Collections.emptyList()));
return recommends.isEmpty() ?
SearchPageGetResponse.of(message.substring(0,message.length()-1) + " 검색 결과가 없습니다.", pagedItems)
: SearchPageGetResponse.of(
String.format("'%s' 으로 총 %s개의 추천글을 찾았습니다.",
searchKey,
recommends.getTotalElements()), recommends);
}
중복이 많다는 말을 간단하게 설명할 수 있는 코드를 가져왔다. 위는 패턴 적용 전 전형적인 방법으로 레포지토리 (EntityManager) 를 활용해서 DI 를 받은 repository 의 메서드들을 목적에 맞게 메소드에서 사용하고 반환한 모습이다. 코드의 중복이 매우 많은 것을 볼 수 있다.
전략 패턴 적용 후 코드
중복을 하나의 메서드로 분리하기
위의 코드에서 중복을 제거하려면 메서드 하나에 각 메서드에서 중복되는 부분은 작성하고, 메서드별로 달라지는 부분은 매개변수로 받는 객체의 동작을 이용해 다르게 정의하는 방식을 사용할 수 있다.
전략 패턴을 사용하면 위 메서드 세 개를 포괄하는 하나의 메서드를 정의할 수 있다. Java 의 제너릭 메서드 정의 방식을 활용하여 T 반환 타입의 메서드를 정의한다. T 반환 타입이란 어떤 반환 타입의 객체도 반환할 수 있다는 것을 의미한다.
살펴보니, 아래와 같은 코드가 중복되고 있었다:
- 매개변수로 입력 받은 사용자 이메일 정보를 검증하는 코드
- 엔티티를 조회하는 코드
- 조회 성공 시 메시지를 반환하는 코드
이 중복들을 모아 작성한 하나의 메서드는 아래와 같다.
public <T> SearchPageGetResponse<T> findWithKeyword(Pageable pageable, String searchKey, ItemSearch<T> searchTool) {
Member member = validate(memberEmail, new MemberValidation(memberRepository));
Page<T> pagedItems = searchTool.search(searchKey, pageable);
String message = searchTool.buildMessage();
return pagedItems.isEmpty() ?
SearchPageGetResponse.of(message.substring(0,message.length()-1) + " 검색 결과가 없습니다.", pagedItems)
: SearchPageGetResponse.of(
String.format("'%s' 으로 총 %s개의 %s 찾았습니다.",
searchKey,
pagedItems.getTotalElements(), message), pagedItems);
}
이 코드에 대한 설명 부터 다음 포스트에서 이어서 하도록 하겠다.
'Project' 카테고리의 다른 글
plugin org.asciidoctor.convert was not found 에러 해결 (0) | 2023.05.05 |
---|---|
[Refactoring] 캐싱 사용해 쿼리 실행 속도 개선하기 (1) | 2023.03.05 |
[Spring Boot] Could not load or find main class 에러 (0) | 2023.02.22 |
[개발일지] Spotify Web API 사용기 (1) (0) | 2023.01.31 |
[리팩토링] JUNIT5 테스트 코드 리팩토링하기 - @ParameterizedTest 와 @MethodSource 활용 (0) | 2023.01.05 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- @RequestBody
- spring
- LazyInitializationException
- Jackson
- N+1
- JPQL
- gitlab
- 깃랩
- ci/cd
- Spring Boot
- DTO
- 지연 로딩
- 실시간데이터
- 역직렬화
- 프로그래머스
- google cloud
- 도커
- docker
- 가상 서버
- 알고리즘
- 인증/인가
- Java Data Types
- DeSerialization
- FCM
- Firebase
- JOIN FETCH
- 코테
- json web token
- JPA
- 기지국 설치
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함