일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- UITextView
- tableView
- 리펙토링
- UICollectionView
- swift documentation
- uiscrollview
- HIG
- ios
- SWIFT
- RxCocoa
- 스위프트
- 클린 코드
- Refactoring
- 리펙터링
- Protocol
- Clean Code
- Observable
- Xcode
- 애니메이션
- clean architecture
- map
- rxswift
- swiftUI
- uitableview
- Human interface guide
- combine
- ribs
- MVVM
- collectionview
- 리팩토링
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] MVC, MVP, MVVM 디자인 패턴 본문
1. MVC
1) 개념
MVC는 Model, View, Controller 세 가지 중점
-> Controller에 많은 부하가 가게되어 해결할 방법 모색(MVP와 MVVM)
※주의할 점 : apple의 설명은 view와 controller는 밀접하게 붙어있는 개념 (view controller 하나로 취급)
2) MVC구현 코드
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
|
import UIKit
struct Person { // Model
let firstName: String
let lastName: String
}
class GreetingViewController : UIViewController { // View + Controller
var person: Person!
let showGreetingButton = UIButton()
let greetingLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
}
func didTapButton(button: UIButton) {
let greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
self.greetingLabel.text = greeting
}
// layout code goes here
}
// Assembling of MVC
let model = Person(firstName: "David", lastName: "Blaine")
let view = GreetingViewController()
view.person = model;
|
2. MVP
1) 개념
*presenter : 증여자
MVC는 View와 Model사이의 의존성이 존재했지만 MVP에서는 의존성을 제거
presenter는 Model로 부터 데이터를 받는 역할을 대신 실천, 또한 view controller의 생명주기에 관여하지 않음
presenter는 view에 쉽게 접근 가능
단순히 Controller의 부하만 떨어뜨린것이 아닌 "테스트 용이성"의 장점도 탄생
2) MVP구현 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
import UIKit
struct Person { // Model
let firstName: String
let lastName: String
}
protocol GreetingView: class {
func setGreeting(greeting: String)
}
protocol GreetingViewPresenter {
init(view: GreetingView, person: Person)
func showGreeting()
}
class GreetingPresenter : GreetingViewPresenter {
unowned let view: GreetingView
let person: Person
required init(view: GreetingView, person: Person) {
self.view = view
self.person = person
}
func showGreeting() {
let greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
self.view.setGreeting(greeting)
}
}
class GreetingViewController : UIViewController, GreetingView {
var presenter: GreetingViewPresenter!
let showGreetingButton = UIButton()
let greetingLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
}
func didTapButton(button: UIButton) {
self.presenter.showGreeting()
}
func setGreeting(greeting: String) {
self.greetingLabel.text = greeting
}
// layout code goes here
}
// Assembling of MVP
let model = Person(firstName: "David", lastName: "Blaine")
let view = GreetingViewController()
let presenter = GreetingPresenter(view: view, person: model)
view.presenter = presenter
|
3.MVVM
* 아이디어 : 중재자(View Model)는 View에 대한 정보에 신경쓰지 말고(의존성 낮춤), 데이터 바인딩*을 통해 구현
- View Model의 실체 : View자체에 데이터 요소까지 같이 존재
ex) UITableView에서는 table(View)이 존재하는 동시에 제목, 서브제목,, 등의 데이터(Model)가 존재
1) 개념
View속에 Controller가 내제되어 있으며, View Model은 View에 대한 데이터 정보를 모르고(뷰 자체 안에서 처리) 데이터 바인딩* 실현(contorller에 대한 부하 감소)
MVC에서는 Controller에 많은 부하를 주었기 때문에 View쪽으로 Controller를 보내고 비어있는 Controller자리에 중재역할을 할 View Model 개념을 삽입한 것 뿐
MVP는 Presenter가 View의 정보를 알고 update하지만, MVVM에서는 View Model이 View의 정보를 모름
- View와 View Model은 1대 n 관계
* 데이터 바인딩(binding) : View와 View Model 사이의 양방향 데이터 흐름 (옵저버 프로퍼티의 didSet과 같은 것이 바인딩의 예 -단방향 바인딩)
2) 소스코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import UIKit
struct Person { // Model
let firstName: String
let lastName: String
}
protocol GreetingViewModelProtocol: class {
var greeting: String? { get }
var greetingDidChange: ((GreetingViewModelProtocol) -> ())? { get set } // function to call when greeting did change
init(person: Person)
func showGreeting()
}
class GreetingViewModel : GreetingViewModelProtocol {
let person: Person
var greeting: String? {
didSet {
self.greetingDidChange?(self)
}
}
var greetingDidChange: ((GreetingViewModelProtocol) -> ())?
required init(person: Person) {
self.person = person
}
func showGreeting() {
self.greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
}
}
class GreetingViewController : UIViewController {
var viewModel: GreetingViewModelProtocol! {
didSet {
self.viewModel.greetingDidChange = { [unowned self] viewModel in
self.greetingLabel.text = viewModel.greeting
}
}
}
let showGreetingButton = UIButton()
let greetingLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.showGreetingButton.addTarget(self.viewModel, action: "showGreeting", forControlEvents: .TouchUpInside)
}
// layout code goes here
}
// Assembling of MVVM
let model = Person(firstName: "David", lastName: "Blaine")
let viewModel = GreetingViewModel(person: model)
let view = GreetingViewController()
view.viewModel = viewModel
|
* 참고한 내용의 출처 : https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52
'Git, CocoaPods, Xcode, Shell' 카테고리의 다른 글
[iOS - swift] 튜토리얼 화면(tutorial screen) 만들기 - PageViewController (programmatically) (0) | 2020.05.08 |
---|---|
[iOS - swift] Xcode, 아이폰에서 앱 테스트하는 방법 (0) | 2020.05.07 |
[iOS - swift] 자신만의 framework 생성 & 사용 (0) | 2020.04.24 |
[iOS - swift] CocoaPods 패키지 관리 도구 (0) | 2020.04.24 |
[iOS - SceneDelegate] iOS13이상 버전의 SceneDelegate (0) | 2020.04.20 |