Swift学徒

iOS 架构模式之 MVP

MVP 构成

在了解 MVC 之后,我们再来看看 MVP:

我们知道实际上 MVC 中的 View 和 Controller 是紧密耦合的。MVP 中的中间者 Presenter 与 View Controller 的生命周期、页面布局没有任何关系,它负责更新 View 的数据与状态。

Presenter 可以只针对特定模块的 View,MVC 中的 Controller 一般会管理一个或多个 Model 和一个或多个 View,而 Presenter 则是 M-P-V 一对一,有更细的粒度和更好的解耦。

UIViewController 是 View

在 MVP 中,UIViewController 的子类实际上是 View 而不是 Presenter。这个定义让结构更加清晰,代价是开发速度的降低。因为必须手动进行数据和事件绑定。

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
}
// 布局代码
}
// MVP
let model = Person(firstName: "David", lastName: "Blaine")
let view = GreetingViewController()
let presenter = GreetingPresenter(view: view, person: model)
view.presenter = presenter

我们不希望 View 和 Model 之间有任何联系, 所以 ViewController(实际上是 View )中不应该处理这种协调逻辑。

我们评估下之前提出的架构特点:

  1. 职能均分:分隔的很清楚。
  2. 容易测试:确实易于测试。
  3. 易用,维护成本低:这个实例的代码量是 MVC 的两倍。换句话说,使用 MVP 意味着代码量大。

万恶胖为首 wechat
关注公众号(ID:SwiftBetter),进一步探讨交流。