所有架构的基础:MVC
架构的演变目的:解耦——接触对象之间的互相依赖,提高代码的复用率,让功能独立开来,提高可移植性。
三种应用层架构:
1. MVP:(Presenter : NSObject)
1.1. 将model对view的赋值,放在Presenter处理;
1.2. 将view的点击滚动等事件,通过代理等方法,让Presenter去处理事件;
1.3. 依然在Controller中处理三者的联系,其实是M、V分别和P的联系。
做到轻Controller。
2. MVVM:(VM : NSObject)
引入view和数据绑定的概念,进一步将数据的展示和数据的操作进行隔离
2.1. VM中的属性要求要与Model一一对应;
2.2. view->vm:在view绑定VM的实现方法中,使用KVO(第三方FBKVO)监控VM中的属性的改变,将新的值赋值给view呈现;
2.3. 在view中持有VM,在view的事件实现方法中,执行VM的方法,这里可以改变VM持有的model的值(记得要再对应赋值给VM的对应属性);
2.4. vm->model:在VM中绑定model,在绑定方法中,将model的值一一对应赋值给VM(这里vm的属性改变就会触发2中的kvo监听);
2.5. 在controller中持有三个对象,调用view的绑定VM的方法,调用VM绑定model的方法。
3. CDD:
不需要书写Delegate就能完成事件的传递
场景:view的结构非常复杂的一个场景,减少代码的书写
比如:聊天界面、直播界面,这类view的层级非常的深的界面,在子view中一层层的把view传递到controller会非常的麻烦。
三层架构:
应用层-ApplicationLayer
服务层-ServiceLayer
数据层-DataAccessLayer
1. 应用层-ApplicationLayer:
1.1. 在应用层中使用MVVM,MVP,MVC之类的架构
1.2. 这里的model,通常是要从服务层获取的(在应用层调用某个服务层的方法,返回一个model)
2. 服务层-ServiceLayer:
2.1. 在服务层中使用工厂类(Factory)管理各种各样的Service类型,一般会写成单例的模式
2.2. model的获取,但事实上是从数据层中返回的,是调用了数据层的工厂单例里,暴露的具体的数据类的方法,返回一个model
2.3. 对应不同的model,有不同的服务类,但是不直接调用这些服务类,而是在工厂单例中暴露这个服务类(将服务类设置为工厂服务类的属性,在工厂类的初始化方法中,初始化)
3. 数据层-DataAccessLayer:
3.1. 在数据层中使用工厂类(Factory),一般会写成单例的模式
3.2. model的创建和赋值,应该写在服务层,在应用层调用某个服务层的方法,返回一个model(但事实上这个model是从数据层中返回的)
3.3. 对应不同的model,有不同的服务类,但是不直接调用这些服务类,而是在工厂单例中暴露这个服务类(将服务类设置为工厂服务类的属性,在工厂类的初始化方法中,初始化)
深度解读MVC和解耦:
对于 View 来说,你如果抽象得好,那么一个 App 的动画效果可以很方便地移植到别的 App 上,而 Github 上也有很多 UI 控件,这些控件都是在 View 层做了很好的封装设计,使得它能够方便地开源给大家复用。
对于 Model 来说,它其实是用来存储业务的数据的,如果做得好,它也可以方便地复用。当然,因为和业务本身的数据意义相关,Model 层的复用大多数是在一个产品内部,不太可能像 View 层那样开源给社区。
说完 View 和 Model 了,那我们想想 Controller,Controller 有多少可以复用的?我们写完了一个 Controller 之后,可以很方便地复用它吗?结论是:非常难复用。在某些场景下,我们可能可以用 addSubViewController 之类的方式复用 Controller,但它的复用场景还是非常非常少的。
如果我们能够意识到 Controller 里面的代码不便于复用,我们就能知道什么代码应该写在 Controller 里面了,那就是那些不能复用的代码
。在我看来,Controller 里面就只应该存放这些不能复用的代码,这些代码包括:
1. 在初始化时,构造相应的 View 和 Model。
2. 监听 Model 层的事件,将 Model 层的数据传递到 View 层。
3. 监听 View 层的事件,并且将 View 层的事件转发到 Model 层。
我个人对于逻辑的抽取,有以下总结。
将网络请求抽象到单独的类中
将界面的拼装抽象到专门的类中
构造 ViewModel
专门构造存储类
小结:
通过代码的抽取,我们可以将原本的 MVC 设计模式中的 ViewController 进一步拆分,构造出 网络请求层、ViewModel 层、Service 层、Storage 层等其它类,来配合 Controller 工作,从而使 Controller 更加简单,我们的 App 更容易维护。
另外,不知道大家注意到没,其实 Controller 层是非常难于测试的,如果我们能够将 Controller 瘦身,就可以更方便地写 Unit Test 来测试各种与界面的无关的逻辑。移动端自动化测试框架都不太成熟,但是将 Controller 的代码抽取出来,是有助于我们做测试工作的。
文章二:objc.io的《Lighter View Controllers》
- 将 UITableView 的 Data Source 分离到另外一个类中。
- 将数据获取和转换的逻辑分别到另外一个类中。
- 将拼装控件的逻辑,分离到另外一个类中。
你想明白了吗?其实 MVC 虽然只有三层,但是它并没有限制你只能有三层。所以,我们可以将 Controller 里面过于臃肿的逻辑抽取出来,形成新的可复用模块或架构层次。
网友评论