-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usecase,Entities,FeedListRepository,FirebaseRemoteDataSource를 생성했습니다. #2
Conversation
GeonH0
commented
Jun 3, 2024
- FeedItem이라는 entity를 정의하였습니다.
- SceneDelegate에서 ViewController의 네이밍을 변경해주었습니다.
- 피드를 가지고 오는 FetchFeedListUseCase와 피드를 검색할때 사용할 SearchFeedListUseCase를 정의했습니다.
- firebase에서 데이터를 가지고오는 FirebaseRemoteDataSource 클래스내에, fetchFeedItems, searchFeedItems의 행동을 정의하였습니다.
- FeedListRepository에서는 FirebaseRemoteDataSource에서 데이터를 가지고오는 클래스 입니다.
- 완료한 부분의 다이어 그램입니다!
} | ||
class FeedListRepositoryImpl: FeedListRepository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개행 부탁드리구요, implement 클래스는 final로 선언하는게 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
23aebe4 수정했습니다!
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
불필요한 개행인 것 같아요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
23aebe4 수정했습니다!
import FirebaseFirestore | ||
|
||
class FirebaseRemoteDataSource { | ||
private let db = Firestore.firestore() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
더 명확한 변수 네이밍이면 좋을 것 같아요.
return | ||
} | ||
guard let documents = querySnapshot?.documents else { | ||
completion(.success([])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
documents가 없어도 성공인건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
성공은 했지만 빈배열일 경우를 생각해서 넣었습니다!
let data = doc.data() | ||
guard | ||
let title = data["title"] as? String, | ||
let imageURL = data["imageURL"] as? [String] else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
배열이 반환되는 거면 imageURLs 와 같이 복수형으로 네이밍하는게 좋을 것 같아요
let imageURL = data["imageURL"] as? [String] else { | ||
return nil | ||
} | ||
return FeedItem(id: doc.documentID, title: title, imageURL: imageURL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) document 모델은 어디서 정의하고 있나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위 document는 파이어 베이스에서 제공하는 문서 자체의 ID를 선언했습니다. 하지만 해당 데이터의 id를 넣어야 할거 같아 수정하겠습니다!
guard let documents = querySnapshot?.documents else { | ||
completion(.success([])) | ||
return | ||
} | ||
let feedItems = documents.compactMap { doc -> FeedItem? in | ||
let data = doc.data() | ||
guard | ||
let title = data["title"] as? String, | ||
let imageURL = data["imageURL"] as? [String] else { | ||
return nil | ||
} | ||
return FeedItem(id: doc.documentID, title: title, imageURL: imageURL) | ||
} | ||
completion(.success(feedItems)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
repository에서 받은 data를 entity로 변환하는 과정(도메인으로 변환하는 과정)을 거치는데,
따로 메서드로 분리하거나 entity 내에서 메서드를 별도로 갖는 것에 대해 어떻게 생각하세요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
적용시켜보겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
response 모델이 정의된 곳에 toDomain()
struct xxxResponse {
let title: String
let imageURLs: [String]
}
extension xxxResponse {
func toDomain() -> FeedItem {
return FeedItem(
title: title,
imageURLs: imageURLs.map { URL(string: $0) }
)
}
}
func toDomain() -> [FeedItem] { ... } // mapping data to domain
struct FeedItem { | ||
let id: String | ||
let title : String | ||
let imageURL : [String] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let imageURL : [String] | |
let imageURLs : [String] |
db.collection("feedItems") | ||
.whereField("title", isGreaterThanOrEqualTo: title) | ||
.whereField("title", isLessThanOrEqualTo: "\(title)\u{f8ff}") | ||
.getDocuments { (querySnapshot, error) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요게 제거가 되는게 맞나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isEqualTo를 사용하는것과 햇갈렸습니다 수정하겠습니다!
|
||
|
||
protocol SearchFeedListUseCase { | ||
func execute(title: String, completion: @escaping (Result<[FeedItem], Error>) -> Void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UseCase에서도 return 없이 Result 타입 completion 으로 처리하는 이유가 있을까요?
(비즈니스 로직 성공/실패는 어디서 핸들링하게 되는걸까요?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usecase에서도 FeedRlistepository에서 데이터를 가지고 받으면서 비동기 작업이 필요할거라 생각해서 completion으로 처리하였습니다!
비즈니스 로직 성공/실패는 viewmodel에서 핸들링 하려고 합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- viewModel이 너무 많은 역할을 하게 되는 것, 뚱뚱해지는 것 방지
- 비즈니스 로직 재사용성을 높임
- SearchFeedListXXX에 대한 응집도 높임
|
||
import UIKit | ||
|
||
class FeedListViewController : UIViewController { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final이 붙어도 좋을까요? (: 옆에 띄어쓰기도 신경써주세요~)
class FeedListViewController : UIViewController { | |
final class FeedListViewController: UIViewController { |
@@ -8,10 +8,10 @@ | |||
import FirebaseFirestore | |||
|
|||
class FirebaseRemoteDataSource { | |||
private let db = Firestore.firestore() | |||
private let firebasedb = Firestore.firestore() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
firebaseDB
=> 배경도 있으면 좋을 것 같아요: 이 작업을 왜 하게 됐는지. 설계 관련 배경이나 진행에 대한 내용도 좋음 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다. 방금 남긴 2건의 코멘트만 확인해서 수정하고 머지 하시면 될 것 같아요.
struct FeedItem { | ||
let id: String | ||
let title : String | ||
let imageURLs : [String] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요거 새로 정의된 값 (Recipe)으로 업데이트만 부탁드릴게요.
@@ -19,7 +19,12 @@ class DefaultFetchFeedListUseCase: FetchFeedListUseCase { | |||
|
|||
func execute(completion: @escaping (Result<[FeedItem], Error>) -> Void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FeedItem이 아닌 새로 정의한 도메인 Recipe로 받도록 변경해야할 것 같아요~
Quality Gate passedIssues Measures |