- 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
MVC
在说MVP之前,先来看看MVC。MVC是苹果推荐使用的一种架构,苹果官方文档对MVC的解释如下:
模型-视图-控制器(MVC)设计模式把应用程序中的对象分成了三个角色:模型、视图或控制器。模式不仅定义了对象在应用程序中扮演的角色,还定义了对象之间的通信方式。这三种类型的对象中的每一种都通过抽象边界与其他对象分开,并通过这些边界与其他类型的对象进行通信。应用程序中特定MVC类型的对象集合有时称为层(layer),例如模型层(model layer)。
MVC是Cocoa应用程序良好设计的核心。采用这种模式的好处很多。这些应用程序中的许多对象往往更易于重用,它们的接口往往定义得更好。具有MVC设计的应用程序也比其他应用程序更容易扩展。此外,许多Cocoa技术和体系结构都基于MVC,并且要求您的自定义对象扮演MVC角色之一。
- 模型对象(Model Objects) 模型对象封装特定于应用程序的数据,并定义操作和处理该数据的逻辑和计算。例如,模型对象可能表示游戏中的角色或通讯簿中的联系人。一个模型对象可以与其他模型对象具有一对多关系,因此有时应用程序的模型层实际上是一个或多个对象图。作为应用程序持久状态一部分的大部分数据(无论持久状态存储在文件或数据库中)在数据加载到应用程序中后都应该驻留在模型对象中。因为模型对象表示与特定问题域相关的知识和专业知识,所以它们可以在类似的问题域中重用。理想情况下,模型对象不应与显示其数据的视图对象有明确的连接,并允许用户编辑该数据。它不应与用户界面和显示问题有关。
通信:视图层中创建或修改数据的用户操作通过控制器对象进行通信,并导致创建或更新模型对象。当模型对象发生更改(例如,通过网络连接接收新数据)时,它会通知控制器对象,控制器对象会更新相应的视图对象。
- 视图对象 (View Objects) 视图对象是应用程序中用户可以看到的对象。视图对象知道如何绘制自身,并且可以响应用户操作。视图对象的一个主要用途是显示来自应用程序模型对象的数据,并启用对该数据的编辑。尽管如此,视图对象通常与MVC应用程序中的模型对象解耦。 因为您通常会重用和重新配置它们,所以视图对象提供了应用程序之间的一致性。UIKit和AppKit框架都提供了视图类的集合,Interface Builder在其库中提供了几十个视图对象。
通信:查看对象通过应用程序的控制器对象了解模型数据中的更改,并将用户发起的更改(例如,通过控制器对象在文本字段中输入的文本)通信到应用程序的模型对象。
- 控制器对象 (Controller Objects) 控制器对象充当应用程序的一个或多个视图对象与其一个或多个模型对象之间的中介。因此,控制器对象是一个管道,视图对象通过它了解模型对象中的更改,反之亦然。控制器对象还可以执行应用程序的设置和协调任务,并管理其他对象的生命周期。
通信:控制器对象解释在视图对象中执行的用户操作,并将新的或更改的数据通信到模型层。当模型对象发生更改时,控制器对象会将新模型数据传送给视图对象,以便它们可以显示该数据。
但是在实际开发中,通常会遇到以下两个问题:
- VC过重
- 耦合度问题
在实际开发中,经常会在VC中将model传入view中来生成View,并且会在view里面更改model,这样就会有耦合度问题。而在vc中,常常有许多繁重的UI,啰嗦的业务逻辑,很长的网络层,难受的代理等使得vc变得臃肿。
我们想要的是做到高内聚,低耦合,也就是谁的事情谁做,并且让VC只做一个任务——搭建依赖关系。
MVP
在MVP中
- 原本写在ViewController层的业务逻辑迁移到Presenter中,较好地解决了Controller层职责过多的问题。
- Presenter层主要处理业务逻辑,ViewController层实现Presenter提供的接口,Presenter通过接口去更新View,这样就实现了业务逻辑和UI解耦。
流程:
用户点击 View(视图) --> 视图响应事件 -->通过代理传递事件到Presenter-->发起网络请求更新Model-->Model处理完数据-->代理或通知给视图(View或是Controller)-->改变视图样式-->完成