Skip to content

[WIP] 검색 뷰 기능 구현 및 아키텍처 적용#39

Merged
EunHee-Jeong merged 13 commits intoTeamRecorDream:developfrom
EunHee-Jeong:feature/#27
Nov 23, 2022
Merged

[WIP] 검색 뷰 기능 구현 및 아키텍처 적용#39
EunHee-Jeong merged 13 commits intoTeamRecorDream:developfrom
EunHee-Jeong:feature/#27

Conversation

@EunHee-Jeong
Copy link
Copy Markdown
Member

👻 작업한 내용

  • 접근 제한자 관련 오류나는 부분 수정
  • Domain, Data, Presentation 계층 코드 작성
  • Presentation 계층 내에 뷰모델 생성

🎤 PR Point

  • 오류가 발생한 부분만 주석 처리했습니다. 코드에도 표시해 놓을테니 확인해주세요!
  • 도메인 계층에 비즈니스 로직이 들어갑니다. 해당 계층은 Entity, UseCase, Interface(= 레포지터리의 프로토콜)로 나뉘며, 유즈케이스를 중심으로 하위 계층을 포함한 곳으로 흘러가도록 하기 위해 start() 함수가 담긴 UseCase 프로토콜을 만들었습니다.
  • 이 부분 PR 수정한 다음 Presentation 계층 마무리하도록 하겠습니다

문제 ㅡ.ㅡ

  • 레포지터리의 인터페이스랑 유즈케이스 파일에서 엔티티를 찾을 수 없다고 오류가 뜸...!
  • 같은 Domain 모듈에서 사용하는 것이기 때문에 처음에는 public을 붙이지 않았는데, 붙여 주지 않았던 것이란 말임? 혹시 이것 때문인가 싶어 붙여 주었지만 똑같이 오류가 사라지지 않음...

📮 관련 이슈

@EunHee-Jeong EunHee-Jeong added 으니짱 🍅 담당자 feat 구현·개선 사항에 관련된 내용입니다. fix 버그를 수정합니다. labels Nov 9, 2022
@EunHee-Jeong EunHee-Jeong self-assigned this Nov 9, 2022
Comment on lines +15 to +16
// func fetchDreamSearchList(query: DreamSearchQuery,
// completion: @escaping(Result<DreamSearchEntity, Error>) -> Void) -> Cancellable?
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. DreamSearchQuery, DreamSearchEntity 부분

Comment on lines +26 to +28
// func execute(requestValue: DreamSearchUseCaseRequestValue,
// completion: @escaping (Result<DreamSearchEntity, Error>) -> Void) -> Cancellable? {
//
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. DreamSearchEntity

L-j-h-c
L-j-h-c previously approved these changes Nov 9, 2022
Copy link
Copy Markdown
Contributor

@L-j-h-c L-j-h-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니당!

Comment on lines +11 to +13
struct DreamSearchResuestDTO: Encodable {
let query: String
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요부분은 저번에 수연이가 얘기한 것처럼 DTO는 제거해도 될 것 같아요!
@Suyeon9911 그런 의도가 맞을까요?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@L-j-h-c 네엡 ~~!!

Comment on lines +12 to +24
public enum Genre: Int {
case comedy
case romance
case action
case thriller
case mystery
case fear
case sf
case fantasy
case family
case etc
case none
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍

Comment on lines +32 to +35
init(provider: DefaultSearchService = DefaultSearchService.shared) {
self.provider = provider
self.initialize()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 service를 Presentation Layer에서 바로 참조하고 있는데, 저희가 의도한 아키텍쳐를 생각했을 때,
프레젠테이션에서는 유즈케이스의 메서드를 통해서 간접적으로 통신의 결과를 받아오는 쪽으로 하면 좋을 것 같습니다!
뷰모델은 유즈케이스에만 의존하도록 해서 책임을 확실하게 분리할 수 있게 되는...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오 반영하겠습니다!!

Comment on lines +44 to +52
Log.event(type: .info, "사용자가 \(query)에 대한 검색을 시작함")
self.currentSearchQuery = query
self.resetCollectionViewDataSource()

return self.searchItemsForTerm()
.catch { error -> Observable<[DreamSearchResult]> in
self.reloadCollectionViewData.onNext(true)
return Observable.empty()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그래서 결론적으로 요 부분에 들어가는 로직이 useCase에 들어가고, 그럼으로써 ViewModel에서는 Input을 받아서 UseCase의 어떤 메서드를 실행해야 할지만 호출해주는 그런 식으로 역할을 분리하면 된다고 이해하고 있습니다.. 물론 구현은 하기 나름이니 취향껏 하시면 될 것 같아요!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아자아자...!!! 🥔

final class DreamSearchViewModel {
// Input
private var provider: DefaultSearchService!
private var collectionViewDataSource: [DreamSearchResultViewModel] = [] // 서브 뷰모델에 해당
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 방식이네여...

Comment on lines +132 to +135
guard let self = self else { return }
DispatchQueue.main.async {
self.dreamSearchCollectionView.reloadData()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withunretained(Self)와 observeOnMain을 사용해서 선언형으로 프로그래밍할 수도 있을 것 같습니다!

Comment on lines +13 to +30
public protocol SearchService {
func searchDreamRecords(keyword: String) throws -> DreamSearchResponse
}

public class DefaultSearchService: BaseService {
public static let shared = DefaultSearchService()

private override init() { }
}

extension DefaultSearchService: SearchService {
public func searchDreamRecords(keyword: String) throws -> DreamSearchResponse {
AFManager.request(SearchRouter.searchRecord(keyword: keyword))
.responseData { response in

}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네트워크 모듈 구현할 때 PR에서 서버 명세서 기준으로 path Parameter 기준으로 크게 5가지로 나뉘어 있어서 Service를 5개만 구현해 뒀었는데, SearchService를 하나 더 구현하는 것이 더 효율적이라고 판단하셨을까요?

image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 잘 모르겠어서 일단 만들었... 허허

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇다면 레코드 서비스에 넣어주시는건 어떤가요? ㅎㅎ 서비스 클래스가 많아지면 혼란이 올 것 같아서요~


import Foundation

struct DreamSearchResponseDTO: Decodable {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 DTO 제거 부탁드립니다...ㅎㅎ

Comment on lines +13 to +16
public protocol UseCase {
@discardableResult
func start() -> Cancellable?
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

start 메서드가 서버통신을 위한 UseCase에만 특별하게 사용 될 수 있을 것 같은데, 네이밍이 조금 넓은 범위를 포함하게 되는 것 같아요... 그리고 start 메서드는 하나의 기능만 가지고 있는 UseCase에 사용될 수 있을 것 같은데 어떤 식으로 사용하실 예정인가요?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유즈케이스에서 필요한 레포지터리 내의 데이터를 패치해올 때(동그라미 부분을 구현할 때) 사용할 예정입니다!
image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하! 레포지토리 인터페이스만으로는 부족한 걸까요?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저 부분에서만 의존성 역전이 일어나는 것이기 때문에 따로 만들었던 것인데요...!
생각을 해보니 네이밍이 범용적이기도 하고, 아직 사용하고 있지 않기 때문에 수정을 해야겠다고 느껴지네욥

Copy link
Copy Markdown
Contributor

@L-j-h-c L-j-h-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생선배 👍 🥇

@EunHee-Jeong EunHee-Jeong merged commit 69419a3 into TeamRecorDream:develop Nov 23, 2022
@EunHee-Jeong EunHee-Jeong deleted the feature/#27 branch November 23, 2022 07:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 구현·개선 사항에 관련된 내용입니다. fix 버그를 수정합니다. 으니짱 🍅 담당자

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 검색 뷰 기능 구현 및 아키텍처 적용

3 participants