美文网首页
MVC、MVP、MVVM

MVC、MVP、MVVM

作者: _Sisyphus | 来源:发表于2018-09-12 23:29 被阅读0次

    MVC:

    Model: 应用数据和处理数据的逻辑;一般对应 JavaBean及一些repository

    View: 屏幕上看见的对象就是View对象;一般对应 Xml 中定义的各类组件

    Controller: 逻辑处理单元,视图与模型对象的联系纽带,响应 View 触发的各类事件、管理 Model 与 View 间的数据流动;Android 里一般对应 Activity、Fragment、Service。

    缺点:

    View 视图层对应xml布局文件,所做的事情相当有限,布局文件中的事件绑定,数据处理都是在acvitity中进行,造成 Acvitity 既像 View 又像 Controller。

    MVC完整的流程: MVC 流程图

    什么是 MVP

    MVP 与 MVC 最大的区别就在与将 Model 和 View 通过 Presenter 隔开了,不再允许其互相直接通信,而所有的消息都是通过 Presenter 这个中间人来传递。而这样做的目的主要是为了将数据和展示划出更明确的界限。

    并不标准的 MVC 到 MVP 的一个转变,减少了 Activity 的职责,简化了 Activity中的代码,将复杂的逻辑代码提取到了 Presenter 中进行处理。与之对应的好处就是,耦合度更低,更方便的进行测试

    各自职责:

    1. Model:负责定义数据(解决什么是数据)
    2. Presenter:负责在Model和View之间,从model里取出数据,格式化后在View上展示(解决如何把数据和用户界面放在一起)。
    3. View:负责担任一个被动界面,用于展示数据。(解决如何展示数据)

    Presenter 作为中间者,同时拥有 View 和 Model 的引用,在它们之间起到桥梁作用,即 Presenter 会主动和 View 和 Model 进行通信

    Model 和 View 必须是完全隔离的,不允许两者之间互相通信,保持对彼此的不感知,这样的好处是彻底将数据和展示分离来开,并且可以独立的为Model去做测试。

    Model 在三者中是独立性最高的,Model不应该拥有对View的引用,而且Model也不需要保存对Presenter的引用对于Presenter而言,Model只需要提供接口,等着Presenter来调用时返回相应数据即可,Model 也不应该去通知View,而是通知 Presenter 来间接的更新View的。

    Presenter 和 Model:基于接口来通信,这样才能把 Model 和Presenter 的耦合度也降到最低,那么在需要改变 Model 内部实现,甚至彻底替换 Model 的时候,Presenter 则是无需随之改变的。这样做带来的另一个好处就是你可以通过 Mock 一个 Model 来对 Presenter 以及 View 做模拟测试了,从而提高了可测试性。

    View 和 Presenter:View是需要拥有对Presenter的引用,但仅仅是为了将用户的操作和事件立即传递给Presenter,为了让 View 和 Presenter 耦合较低,View也只应该通过接口与 Presenter 通信,从而保证 View 是完全被动的,一方面它由用户的操作触发来和Presenter通信,另一方面它完全受 Presenter 控制,唯一需要做的事情就是如何展示数据。

    三者之间的关系:

    • View 和 Model 之间没有联系

    • View 通过接口向 Presenter 来传递用户操作

    • Presenter 通过接口和 View/Model 来联系。

    • Model 不主动和 Presenter 联系,被动的等着 Presenter 来调用其接口

      View <- 接口 <- Presenter ->接口 -> Model
      View -> 接口 -> Presenter <- 接口 <- Model

    为什么使用 MVP

    在 MVC 中,XML视图功能太弱,所以 Activity 既要负责视图的显示又要加入控制逻辑,往往需要同时承担和 V 和 C 两部分职责,代码过于臃肿,不好维护和扩展,比如说当修改数据获取方式的时候,需要修改的地方太多,而且需要把整个业务逻辑全部看一遍,且容易修改错;而当使用的MVP模式时,只需要修改 Model 中获取数据的方式,因为 Presenter 层拿到的是 Model 的接口,只关心 Model 层返回的数据,至于你的数据是从网络还是数据库还是本地数据库文件获取的,根本不必关心。 MVP 让 Activity 成为真正的 View。

    优点:

    1. 分层更加清晰明确
    2. 更利于扩展和维护
    3. 方便对于 Model 进行单独测试

    缺点:

    1. 类比较多
    2. 由于对视图的渲染放在了 Presenter 中,所以视图和Presenter的交互会过于频繁。
    3. 如果 Presenter 过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了

    MVVM

    ViewModel:
    创建关联,将 Model 和 View 绑定起来,如此之后,我们 Model的更改,通过ViewModel 反馈给 View,从而自动刷新界面。DataBinding是一个实现数据和UI绑定的框架,是构建MVVM模式的一个关键的工具,它是支持双向绑定的。

    ViewModel 只做和业务逻辑和业务数据相关的事,不做任何和UI、控件相关的事,ViewModel 层不会持有任何控件的引用,更不会在ViewModel中通过UI控件的引用去做更新UI的事情。ViewModel就是专注于业务的逻辑处理,操作的也都是对数据进行操作,这些个数据源绑定在相应的控件上会自动去更改UI,开发者不需要关心更新UI的事情。

    总结:
    View 层的 Activity 通过 DataBinding 生成 Binding 实例,把这个实例传递给ViewModel,ViewModel 层通过把自身与 Binding 实例绑定,从而实现 View 中layout 与 ViewModel 的双向绑定。mvvm的缺点是数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。

    databinding

    1. gradle 中
    dataBinding {
                enabled true
        }
    
    1. xml 中
      最外层使用 layout 标签,通过 data 标签将该 View 对于的 Model 导入进来,然后在控件中比如 TextView 的 text 属性就可以和该 Model 的属性绑定。
      支持运算符操作。如三元
      支持事件绑定。

    2. Activity 中

    ActivityMainTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main_test);
    binding.setTest(testModel);
    

    不需要写 findViewById 和 butterknife,只需要

    android:id="@+id/tv"
    TextView tv = binding.tv;
    

    部分参考: https://www.jianshu.com/p/50c7124f408e

    相关文章

      网友评论

          本文标题:MVC、MVP、MVVM

          本文链接:https://www.haomeiwen.com/subject/wjzbgftx.html