现代程序框架模式,MV-X

mv-x的含义

M:Model

V:View

X:View和Model的桥梁

MVC

C:Controller

大致定义:

View和Model一般没有交集,它们的交流通过Controller来进行,即:

Model和View由Controller来管理,一般除了View的响应由Controller来实现(由View传向Controller),Model的变化及View的设置都会在Controller来实现(Controller单向传给其余两个),View本身不会和Model有任何交集或很少交集(Model的变化直接反映在View上)

如果三者的负责不均匀就会有各种变种的MVC,最著名的是Massive View Controller(Controller负责绝大部分的事,Model和View的存在感太弱,这种其实已经很接近MVP了)

MVP

P:Presenter

MVP的出现主要是为了完全切断MVC中View和Model的联系,Presenter负责Model的变化,同时负责View(Controller)的变化,同时接受处理View的事件,从而减少维护的成本(需要修改时代码都放在一块了)

传统的iOS结构其实更接近MVP, viewController就相当于Presenter,什么都写在Presenter中

MVVM

VM:ViewModel

实际关系:

View(Controller) <-> View Model <-> Model

View 负责按照处理好的数据显示界面

View Model 负责更新数据和展示数据到View上,同时数据的测试只需要通过View Model就能实现,View Model的重点是为了把View和Model完全隔离开

Model 只负责原本Controller中的数据处理

在传统的 MVC 上简化 View 和 Controller的负担(实际上iOS架构基本是把这两个合并),顺便降低了耦合性,如果愿意的话,实际上ViewModel是可以复用的:把View,Model直接的映射抽象化,把常用的方法放进去,但这样还不如做成View的分类

VIPER

一种什么都通过协议联系的结构

优点

解藕程度几乎是所有MVC类型结构中最高的,而且与Core Data几乎是绝配

缺点:过于啰嗦,甚至在小模块中就需要有十几二十个类(典型的例子就是https://www.objccn.io/issue-13-5 这个例子,两个界面加上Core Data就20多个类,还得依照要求配套协议,如果按照传统的MVC来实现,不算Core Data,最少3个类就能实现了)

View视图

展示界面,接受用户事件

Entity实体

相当于MVC的Model,并且是纯数据类,所有数据的处理都由Interactor接管

剩下的三个基本是实现协议的NSObject,三者不会直接关联,而是通过协议联系,甚至Presenter和Controller之间也是通过协议联系:

Presenter展示器

相当于MVVM里ViewModel的主要工作,把View的事件传递给Interactor,并且处理Interactor的回调给其他Presenter

实际上Presenter也不与View交互,而是与Controller交互,但iOS里的View和Controller基本是合并的状态所以就直接说是View了

Router路由(有些地方也会称为WireFrame)

功能基本等价于iOS中的navgationController,Router负责管理各个Presenter,创建Controller,匹配Presenter和Controller,跳转Controller

Interactor交互器

负责业务分析,(联网)读取数据,接受Presenter传递过来View的事件,处理并更新Entity,回调Presenter工作

Interactor还会和data manager/network manager打交道,分离数据的读写

实际上Controller还是存在的,只是它的工作变成了准备View和调用Presenter,接受Presenter的回调

VIPER大致拆为两部分

View层:View-Presenter-Router 和 数据层:Interactor-Entity

这两部分通过Presenter和Interactor通信,尽可能解藕其他部分

实际上只要能把View,Entity完全分开(通过Interactor分开,只有Interactor能访问Entity),只要符合这点,viper可以以任意组合进行

在把View和Entity完全分开后,要怎么用Entity设置View呢?

这里可以为Entity做一层桥接器,Presenter通过桥接器把Entity转换成能识别的格式(View的专属ViewModel,这里的Model就真的是Model的意思了)

完整的viper大概长这样(不是绝对的,但View和Model分开是主要目的):

Pasted Graphic 2.jpg

由上图可以看出。虽然本质还是一个MVC,但解藕程度已经非常高了,不同的Entity通过不同的Converter可以用于不同的View,缺点是需要的类真的超多。

Interactor和NetworkManager/DataManager直接通信也存在一个中间模型的转换用作解藕

好处就是测试数据正确性的时候,由于View完全独立于数据层,直接对interactor进行测试就能跳过View那部分了,而且开发流程可以转变为,先编写测试代码,然后实现数据层的正确性后,再开始开发View层,还可以先编写Presenter的测试代码再实现界面,最后编写UITest

实际上这种多协议的结构,用RAC这类框架能够更好的简化调用

总结:适合复用程度高的项目,同时要求整个项目都按照一样的结构构件每个模块的时候,可以取得最大优势,由于过于依赖不同的Model和通过协议回调,viper更适合使用Swift的项目

ModelController

简单的解藕还可以通过ModelController把对Model数据的操作,计算,甚至是数据的更新都放到ModelController中,用的时候就初始化一个ModelController来用,其余时候都只需要用Model就行,虽然叫ModelController,但ModelController是跟View绑定的...操作的事务都是为了View来操作Model

ModelController为了解藕都不会暴露Model,而是通过提供同质的pubic属性把Model内的数据合成并传递出去(通过ModelController进行单向的数据流动),如:

class UserModelController {

    private var user: User
        init(user: User) {
        self.user = user
    }

    var displayName: String {
        return "(user.firstName) (user.lastName)"
    }
}

该例子来自:https://www.swiftbysundell.com/posts/model-controllers-in-swift ,更具体的ModelController可以查看该文章(纯英文)

通过block回调/代理/KVO等方式在Model变化/更新的时候通知出去更新View

其实ModelController和ViewModel很像

喵神在MV-X的基础上总结了另一套以单向数据流为基础的结构,相关的总结可以查看:
https://www.jianshu.com/p/59b3aa74d1df

你可能感兴趣的:(现代程序框架模式,MV-X)