在之前對於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框架的使用及原理啦。