FEW의 메인 화면에는 아래 사진에서 확인할 수 있는 3가지 상태의 워크북 카드가 정렬되어 제공됩니다.
정렬 기준은 아래와 같습니다.
- 기본 정렬 기준
- 구독자 수가 많은 워크북을 우선 노출합니다.
- 구독자 수가 동일하다면 최근에 생성된 워크북을 우선 노출합니다.
- 멤버가 로그인한 경우
- 멤버가 구독 중인 워크북을 우선 노출합니다.
- 여러 워크북을 구독 중이라면 Day가 더 많이 진행된 것을 우선 노출합니다.
- 멤버가 구독 완료한 워크북을 나중에 노출합니다.
- 멤버가 구독하지 않은 워크북은 기본 정렬 기준을 따릅니다.
- 멤버가 구독 중인 워크북을 우선 노출합니다.
워크북은 FEW 프로젝트의 주요 개념으로 다양한 화면에서 그에 맞는 정렬 기준을 가진 요구사항이 추가될 것이라 예상합니다.
이에 저는 전략 패턴을 활용하여 앞으로 추가될 정렬 기준에 대응할 수 있는 코드를 개발하였습니다.
val orderStrategy = when {
useCaseIn.viewCategory == ViewCategory.MAIN_CARD && useCaseIn.memberId != null -> WorkBookOrderStrategy.MAIN_VIEW_AUTH
useCaseIn.viewCategory == ViewCategory.MAIN_CARD && useCaseIn.memberId == null -> WorkBookOrderStrategy.MAIN_VIEW_UNAUTH
else -> WorkBookOrderStrategy.BASIC
}
요청에 따라 전략을 선택할 수 있도록 구현하였습니다.
val orderedWorkbooks = when (orderStrategy) {
WorkBookOrderStrategy.MAIN_VIEW_AUTH -> {
BrowseMemberSubscribeWorkbooksInDto(useCaseIn.memberId!!).let { dto ->
workbookSubscribeService.browseMemberSubscribeWorkbooks(dto)
}.map {
MemberSubscribedWorkbook(
workbookId = it.workbookId,
isActiveSub = it.isActiveSub,
currentDay = it.currentDay
)
}.let { subscribedWorkbooks ->
AuthMainViewWorkbookOrderDelegator(workbookDetails, subscribedWorkbooks)
}
}
WorkBookOrderStrategy.MAIN_VIEW_UNAUTH -> {
BasicWorkbookOrderDelegator(workbookDetails)
}
else -> BasicWorkbookOrderDelegator(workbookDetails)
}.let { delegator ->
workbookOrderDelegatorExecutor.execute(delegator)
}
interface WorkbookOrderDelegator {
/**
* 워크북을 정렬합니다.
* */
fun order(): List<WorkBook>
}
정렬에 필요한 데이터를 포함한 공통인터페이스 WorkbookOrderDelegator를 구현한 클래스를 생성합니다.
BasicWorkbookOrderDelegator: workbookDetails 조회 시 정렬된 값을 그대로 사용합니다.
AuthMainViewWorkbookOrderDelegator: workbookDetails 조회 결과와 subscribedWorkbooks 조회 결과를 함께 사용하여 정렬을 수행합니다.
class WorkbookOrderDelegatorExecutor {
fun execute(delegator: WorkbookOrderDelegator): List<WorkBook> {
return delegator.order()
}
}
WorkbookOrderDelegatorExecutor에서 WorkbookOrderDelegator 인터페이스를 파라미터로 받아 정렬된 값을 반환합니다.
execute 메서드의 파라미터에 어떤 타입의 클래스가 전달되는가?를 통해 BDD 테스트의 구현이 가능합니다.
제가 생각하는 위의 구현 코드의 장점은 아래와 같습니다.
- 다른 요청, 같은 정렬 기준인 경우 별도의 개발이 필요하지 않습니다. 오직 정렬 기준에 따라 개발 필요를 판단할 수 있습니다.
- 정렬 기준이 추가된다면 해당하는 WorkbookOrderDelegator를 개발하여 추가하면 됩니다.
- WorkbookOrderDelegator가 정렬에 대한 책임만을 가지고 있기에 테스트 코드를 작성하기 편합니다.
'개발' 카테고리의 다른 글
SpringBoot에서 HTTP 요청을 처리하는 과정을 살펴보며 (DispatcherServlet) (0) | 2024.08.26 |
---|---|
Pinpoint 도입 이모저모 (0) | 2024.08.22 |
하나의 유즈케이스에서 여러 번 쿼리를 요청하면? (0) | 2024.08.19 |
캐싱을 도입하며 (0) | 2024.07.30 |
jOOQ 사용기 (2) | 2024.07.23 |