MVC->MVP->MVVM架构完整演变过程剖析

在之前对于MVP这种架构风格已经进行了深入的学习了,接下来则打算学习一下MVVM这种架构,MVC、MVP、MVVM这三者基本上会被人一起问到的,而对于MVVM,google官方推出了一个dataBinding的MVVM的框架,而从学习的角度直接上框架并非是一个非常好的学习方式,所以这次就手把手的一步步通过一个小案例来实现MVVM框架,对其原理有一个本质的了解,这样在下一次学习dataBinding时也能做到心中有数。

MVC:

思想:

架构理解:

对于上图的理解,简单描述整个过程就是用户触发了View的一个事件,然后则会转到Controller中进行处理,而它又会去操作Model,最终Model处理完了会更新到UI上来。这里用一个伪代码来模拟一下这个过程:

而其实有些MVC会是这样的一个关系:

具体实现:

接下来则回到Android的代码上来,先来简单搭个框架:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/et_data1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/et_data2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btn_save"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="save" />

</LinearLayout>

没啥好解释的,默认Android的这个代码框架就属于MVC风格的,这个都耳熟能详了,这里还是啰嗦一下:对于V来说就是我们的布局文件,而M则是DateCenter这个类,而C则是MainActivity。那为啥会出现MVP、MVVM这种新的框架出来呢?因为目前MVC框架中的Activity太重了,跟M和V都进行耦合在一块了,所以MVP出现了。

MVP:

思想:

架构理解:

其中可以看到跟MVC中最大的区别在于MVP的Model和View之间没有引用了,然后之前的Controller变成了Presenter了。

具体实现:

接下来咱们来将它改造成MVP,首先先来新建一个P:

然后它会操作Model,所以这里将这个代码牵移到P中:

此时Activity调整为:

此时一个基本的MVP就出现了,其中“View跟Controller给拆开了,并提取出了一个Presenter”,目前这个基本的MVP框架中P是直接持有了具体Activity的引用,然后目的是用来调用它里面的刷新界面的方法:

 

很明显对于P来说不需要用到MainActivity中的所有信息,只需要知道这个界面是如何更新UI的就行了,所以直接持有Activity的引用设计不是太合理,面向接口编程是最提倡的,也就是能只获取最小的信息则就获取最小的,这样会解耦,所以咱们将其抽象成一个接口,里面会存放各个跟UI相关的操作接口:

思考:在上面中加粗了一句话“View跟Controller给拆开了,并提取出了一个Presenter”,那能否不提一个Presenter,而达到同样的效果呢?其实是可以的,而这种写法在实际工作中也是很频繁的,下面改装一下,这里先将建几个包将其分开一下:

而这里则对MvcActivity传统的写法进行调整一下:

怎么能让控件层与View之间耦合不那么紧呢?其实就是想办法把这段代码给去掉:

其实就是将这个设置封装到View里面既可:

package com.android.mvc_mvp_mvvm_demo.mvc;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.android.mvc_mvp_mvvm_demo.R;

public class DataView extends LinearLayout {

    private EditText et_data1;
    private EditText et_data2;

    public DataView(Context context) {
        super(context);
    }

    public DataView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public DataView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void showData(String[] data) {
        et_data1.setText(data[0]);
        et_data2.setText(data[1]);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        et_data1 = findViewById(R.id.et_data1);
        et_data2 = findViewById(R.id.et_data2);
    }
}

为啥要改上面这种比较简单的代码呢?其实这里是要来对于很多人都说的:“MVP要比MVC要好,MVC的View和Controller都混到一块”这样的观点持怀疑态度,很明显通过上面的这样改良,也没有提取出一个P,跟MVP的效果差不多呀, 那为啥要说MVP比MVC要好呢?可能有些人会说MVP不是会提取出一个View的接口嘛,那对于上面改良的这种代码也可以提取呀,下面试一下:

所以其实对于MVC和MVP框架本质来说其实是一样的,当然细节会有不同,这种观点其实没必要较真,只是为了了解其了本质才这样挖掘的,而平常在讨论这俩框架的区别时,还是可以说:“Android自带的框架就是MVC,而抽出来一个P层的则是MVP”。

MVVM:

接下来则来看最后一种架构了,这种目前还木有在真实项目中用过,但是对于它的了解也早就有所耳闻,相比MVP而言,它的数据如果发生变化了会立马反馈到UI上,而不需要通过回调通知UI进行刷新,反过来如果UI更新了数据状态也会自动到去将Model中的数据给自动更新 。

思想:

具体实现:

先来新建一个ViewModel:

此时Activity就可以这样来调用了:

 

接下来要实现数据自动显示在界面上该如何修改呢?怎么明显Activity跟ViewModel需要进行绑定才行,所以新建一个类:

在这里面则需要监听textView和text的变化,对于TextView的变化监听有现成的API这个不用操心,但是对于第二个参数text很显然不能,所以此时我们得将ViewModel中的这块得封装一下才行:

具体修改如下:

此时回到ViewBinder类中:

哦,原来双向绑定的核心是这么搞的,就是哪方改变了再通知另一方,好接下来咱们再回到ViewModel中:

 接下来则可以进行Activity与ViewModel的绑定了,先来在ViewModel定义一个绑定接口供Activity来调用:

好,接下来调用一下:

至此一个简单的MVVM框架就搭建完了,说实话还是有些麻烦的,不过好在Google针对MVVM推出了成熟的框架,如开篇有说,DataBinding,商用的话基本上会基于这个框架来进行MVVM的开发,这次对于MVVM的核心原理了解了之后,下一次就准备来学习一下DataBinding框架的使用及原理啦。

posted on 2020-03-11 21:13  cexo  阅读(1217)  评论(0编辑  收藏  举报

导航