一、 模式的历史 —— 解决复杂的GUI应用的代码组织问题
所以这些都是为了搞定GUI的繁琐的代码组织、职责划分问题
- MVC
-
Controller: 管理所有的业务,等待View发请求,更新代码致Model
-
View:请求发送给Controller,也可以直接更新Model(Model通过事件也可以更新View)
-
Model:接受来自Controller的请求,也有View的请求,
-
问题:View和model直接存在依赖关系,View又和Controller存在依赖,导致职责并不单一
image.png
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()
- MVP
MVC的改良版本 —— 解决View耦合较高的问题,将大部分处理放置于Presenter中
- Presenter:接受View的请求,更新Model数据,也通过IView的接口来更新View
- View:提供更新自己页面的接口,交互请求Presenter
- Model:接受来自Presenter的请求,更新数据也发送给Presenter
![](https://img.haomeiwen.com/i14742259/069410fb8ad82c79.png)
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
- MVVM
MVP的改良版本 —— 解决Presenter要显示调用IView接口的问题,转而使用实现好的Data Binding Engine(类似于get;set;)
- VM :存储的数据及状态,其本身存储在ViewLogic这里,接受View的更改请求,也接受model的更改,自动渲染到View
- View:单纯的展示数据和绑定VM,等待VM的变化导致其View发生变化
- Model: 与VM交互,VM更新Model,然后Model更改后会更新VM,从而由 Data Binding Engine来更新View
![](https://img.haomeiwen.com/i14742259/b6a8042144906067.png)
![](https://img.haomeiwen.com/i14742259/75d34b58eb38261c.png)
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
网友评论