Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
Tags
- Protocol
- ios
- Xcode
- UITextView
- clean architecture
- collectionview
- Refactoring
- rxswift
- RxCocoa
- 리팩토링
- swift documentation
- 클린 코드
- 스위프트
- 애니메이션
- tableView
- HIG
- Observable
- SWIFT
- Clean Code
- ribs
- combine
- UICollectionView
- MVVM
- 리펙터링
- Human interface guide
- 리펙토링
- uiscrollview
- map
- uitableview
- swiftUI
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Factory 패턴으로 비즈니스 모델을 UI모델로 변경하는 좋은 방법 (UI 모델, 비즈니스 모델, 도메인 모델, 데이터 모델) 본문
iOS 응용 (swift)
[iOS - swift] Factory 패턴으로 비즈니스 모델을 UI모델로 변경하는 좋은 방법 (UI 모델, 비즈니스 모델, 도메인 모델, 데이터 모델)
jake-kim 2024. 3. 13. 01:22비즈니스 모델을 UI 모델로 변경하기
- 만약 MVVM을 사용한다면, API호출을 통해 얻은 데이터들을 ViewModel에서 받아오고 UI 쪽으로 다시 전달해주어야 하는데 정석으로는 UI / Domain / API 세 계층 모두 모델을 다르게하여 의존성을 줄이는 것이 이론적으로 좋은데 이 때 모델을 다르게하면 model간 변환하는 로직이 필요
- Domain에서 UI모델로 데이터를 변환할 때, Factory 패턴을 사용하면 로직 분리가 용이
- Factory라는 의미는 단순히 UI모델로 변경하는 작업 뿐만이 아닌, UI모델에서 필요한 값들도 같이 넣어주도록 구현
- 만약 api로부터 (age: 20)와 같은 값을 가져오는 경우 UI에서는 20살이라고 표현해야할 때 Factory에서 "20"과 "살"을 결합하여 생성하는 것
ex) API와 Domain에서 모델이 같다고하고 UI 모델만 다른 경우, UI모델로 변경하는 코드
- bad case: ViewModel에서 직접 변경하는 경우
- ViewModel에서 requestAPI를 하여 API에서 얻어온 [Int]타입들을 UI에서 필요한 Model 타입으로 변경 후 UI쪽에 updateUI를 호출
- 사용된 MVVM 모델 구조 설명은 이전 포스팅 글 참고
final class ViewModel: ViewModelable {
...
// MARK: Output
var output: RxSwift.Observable<State> {
outputSubject
}
private var outputSubject = PublishSubject<State>()
// MARK: Input
func input(_ action: Action) {
switch action {
case .viewDidLoad:
requestAPI()
.subscribe { [weak self] data in
self?.dataSource = data
.map { Model(n: String($0) + "번째") }
self?.outputSubject.onNext(.updateUI)
}
.disposed(by: disposeBag)
}
}
}
func requestAPI() -> Single<[Int]> {
.just((1...10).map { $0 })
}
- good case: Factory 패턴을 사용하는 경우
(factory 정의)
enum SomeFactory {
static func makeFirstUIModel(apiResponse: [Int]) -> [Model] {
apiResponse
.map {
.init(n: String($0) + "번째")
}
}
}
- viewModel에서 사용
- SomeFactory는 protocol로 표현하고 ViewModel에서 factory도 주입받을 수 있도록 구현하면 더욱 베스트 (testable)
requestAPI()
.subscribe { [weak self] data in
// self?.dataSource = data
// .map { Model(n: String($0) + "번째") }
self?.dataSource = SomeFactory.makeFirstUIModel(apiResponse: data)
self?.outputSubject.onNext(.updateUI)
}
.disposed(by: disposeBag)
정리
- Factory로 구현하면 데이터 모델을 convert하는 긴 코드들이 factory에 모여있으므로 응집도가 크고 코드 관리가 용이
- 위에서 알아본 UI에 필요한 "번째" 문구같은 것도 Factory에서 담당하게 되면 ViewController의 역할은 단순히 데이터를 표현하는 역할로 담당할 수 있게하여 뷰의 몸집이 커지지 않고 역할을 분명하게 가능
* 전체 코드
'iOS 응용 (swift)' 카테고리의 다른 글
Comments