新接手的项目使用的整体 App 架构是 MVP 架构和我之前惯用的 MVC 架构并不一样,所以花时间重新熟悉了下这两个架构,发现了很多之前没有注意到的点,值得简单记录一下。
传统的 MVC 的架构如图
MVC 最早是在20世纪80年代为程序语言 SmallTalk 发明的一种软件架构。但是传统的 MVC 和苹果改进后的 MVC 架构并不一样,苹果预期实现的 MVC 架构是这样子的。
这种架构和上面传统的区别在于,下面苹果改进的这种 MVC 架构隔离了 View 和 Model,这两个组件想要通信必须要通过 Controller 才行。
我自己理解用简单的语言说就是,传统的 MVC 架构里 View 是可以持有 Model,并不需要通过 Controller。而下面这种 MVC 架构里 View 不能直接持有 Model,两者都需要被 Controller 持有,最终在 Controller 层面实现 View 和 Model 的通信。
在传统的 MVC 里,Controller是非常轻量级,它只是负责转发请求以及进行用户交互的响应,反而是 View 比较重需要做很多数据转换,一些业务逻辑。在苹果改进后的架构里 Controller 实现了较重的责任,View 只是作为展示层去进行展示,并不需要关心任何业务逻辑了。
事实上,苹果改进的这种架构并不算严格意义上的 MVC,叫它 MVP 更加合适。 结合上面的说法,MVC 和 MVP 之间的区别主要在于,是否对数据和视图模型进行隔离。
但是苹果自己在实现自己的 MVC 的时候出现了严重的问题,就是 View 和 Controller 混在一起,被 UIViewController 这个类统一实现了,如图所示
View 和 Controller 没办法很好的拆分这个问题导致了 MassiveController 的出现,比如 Controller 应该不需要关心 View 的布局问题,但是 UIKit 框架在 UIViewController
里面设置了 viewDidLayoutSubviews
这样的布局入口函数,让开发者去进行视图布局,等等一坨坨代码就来了。
所以基于苹果 MVP 版本的改进版的 MVP 出现了,让 UIViewController
仅仅作为 View,引入 Presenter 作为 Model 和 View 的通信桥梁,我现在手头的新项目就是用这种架构做的。
一个摘自网上的 MVP Demo
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
综上,还是要理解清楚 MVC 和 MVP,理清楚到底 MVC 到底是什么样子的,要不然 MVC 和 MVP 因为各种历史原因和不同人的不同理解就是傻傻分不清楚。
参考地址: