国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MVVM_Android-CleanArchitecture

icattlecoder / 1398人閱讀

摘要:業(yè)務(wù)層,業(yè)務(wù)層,是最為核心的一層。對(duì)于和的狀態(tài)保存恢復(fù)也通過(guò)處理。對(duì)于的綁定操作和命令操作都是暴露的,也易于測(cè)試。需要注意的是標(biāo)簽的節(jié)點(diǎn)中要使用到根節(jié)點(diǎn)中標(biāo)簽里設(shè)置的的話需要這樣設(shè)置抽象類中設(shè)置了和注解,只起到清晰提醒作用。

原文發(fā)表于:Rocko"s blog(rocko.xyz)] - MVVM_Android-CleanArchitecture

前言

"Architecture is About Intent, not Frameworks" - Robert C. Martin (Uncle Bob)

Uncle Bob 的這句話套在 MVVM 上也是適用的, MVVM 也僅僅是架構(gòu)模式(Architectural pattern),其有一套自己的理論概念(pattern)而不是規(guī)定的具體實(shí)現(xiàn)(或 Frameworks)。早之前在知乎上相關(guān)問(wèn)題的回答(android UI設(shè)計(jì)MVVM設(shè)計(jì)模式討論?)中也簡(jiǎn)單提到過(guò) MVVM 了,M-V-X 的關(guān)系如上圖,那么這一次博主把 Fernando Cejas(android10) 的 Android-CleanArchitecture 項(xiàng)目中的 MVP 實(shí)現(xiàn)重構(gòu)成了用 MVVM 來(lái)實(shí)現(xiàn)。所以看這篇文章最好是先搞清了 Fernando Cejas(android10) 的 Android-CleanArchitecture sample app 和對(duì)應(yīng)的兩篇文章(見(jiàn)參考)。整個(gè)歷程也算比較愉快,沒(méi)什么不良反應(yīng),這篇文章理所當(dāng)然會(huì)重點(diǎn)說(shuō)說(shuō) MVVM 的實(shí)現(xiàn)、 Data Binding 等相關(guān)的東西。那為什么擁抱 MVVM 呢。當(dāng)然是 Google 推出官方的 data binding 啦,下一次的 Android MVVM 熱潮應(yīng)該就是 data binding 放出正式版了。

分層架構(gòu)與 M-V-X

首先還是先來(lái)說(shuō)說(shuō) 分層架構(gòu)MVC or M-V-X 之間的關(guān)系。分層架構(gòu)是一種常見(jiàn)的軟件應(yīng)用架構(gòu),在 Java 程序中可以算是一種應(yīng)用標(biāo)準(zhǔn)了,通常又叫 N 層架構(gòu),而最常見(jiàn)的是 3 層架構(gòu),它包含如下 3 層:

展示層(Presentation tier),也稱為 UI 層,也就是程序的界面部分。

業(yè)務(wù)層(business logic(domain) tier), 業(yè)務(wù)層,是最為核心的一層。

持久層(Data tier),數(shù)據(jù)持久層。

3 層架構(gòu)是存在物理上分層概念的,從上往下即展示層、業(yè)務(wù)層、持久層,也從上往下由上一層依賴下一層。不同層之間也是 高內(nèi)聚低耦合 的體現(xiàn),層內(nèi)高內(nèi)聚,層間低耦合, 是層內(nèi)具體工作的高度抽象。低耦合則是依賴倒轉(zhuǎn)原則體現(xiàn)出來(lái),高層依賴于下層的抽象而不是具體。

接下來(lái)先說(shuō) M-V-X 的鼻祖 MVC,Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces.,所以 MVC 模式是為用戶界面設(shè)計(jì)的,在 3 層架構(gòu)中,MVC 是屬于展現(xiàn)層的部分,所以 MVVM 作為 MVC 的演進(jìn)在與分層架構(gòu)的關(guān)系上也是一樣。經(jīng)常會(huì)看到 3 層架構(gòu)與 M-V-X 混為一談的內(nèi)容,這是不正確的,雖然都是 3 部分的內(nèi)容但是不能 簡(jiǎn)單地 把兩者的每一部分對(duì)應(yīng)起來(lái),我們應(yīng)該理解為,在分層架構(gòu)中 M-V-X 是在展示層(Presentation tier)的應(yīng)用。這些軟件工程理論的東西就這樣了,都是大師們留下來(lái)的東西,不要隨便套上自己的概念。

Android-CleanArchitecture

Fernando Cejas(android10) 的 Android-CleanArchitecture 項(xiàng)目中也是采用典型的 3 層架構(gòu),其中 Presentation 展現(xiàn)層采用了 MVP 模式,如果還未了解過(guò) MVP,可以看看我之前寫的文章:Android中的MVP。不過(guò) Google 推出官方的 data binding 之后我覺(jué)得基本可以不用采用 MVP 了,在 M-V-X 中, MVP 與 MVVM 算是比較接近的了但 MVP 中的一堆 View 接口也是讓人頭疼的,而擁有 data binding 的 MVVM 則解決了這個(gè)問(wèn)題,所以請(qǐng)大膽擁抱 MVVM。So,下面幾點(diǎn)是當(dāng)中除 MVVM 外涉及到的東西,MVVM 放到下一節(jié)再講。

Dagger

自帶 Dagger 信仰光環(huán)者障眼之術(shù)開(kāi)啟, 哈哈,你們看不到接下來(lái)的這句話了。。我現(xiàn)在也是持不贊成 di 的觀點(diǎn)的人(在 Android 中、、、),可以看看這場(chǎng)撕逼:依賴注入是否值得?。結(jié)果就是我把原項(xiàng)目的依賴注入模塊去掉了,對(duì)于測(cè)試中的類中的成員變量來(lái)說(shuō)本來(lái)就是 Mock 抽象接口,那就直接對(duì)接口或抽象類直接 Mock 操作就可,畢竟依賴注入的解耦依然是取決于需要注入的對(duì)象的抽象,維護(hù)依賴注入模塊(Module)也是負(fù)擔(dān),測(cè)試代碼中又要多寫一套注入控制的 Dagger Module 代碼。。

RxJava、RxAndroid

先說(shuō) AsyncTask,對(duì)其已經(jīng)不再想吐槽,這么重要的異步實(shí)現(xiàn),版本間(Android Api)代碼改來(lái)改去,又順序又無(wú)序、又單線程執(zhí)行又并發(fā)執(zhí)行、內(nèi)存泄露、、、。所以對(duì)于采用 RxJava 即使不采用函數(shù)響應(yīng)式編程的大概念,用它來(lái)替換 AsyncTask 和 Thread + Handler 也是推薦的。此外使用 Rx 后也不需要事件總線的框架了,對(duì)于回調(diào)監(jiān)聽(tīng)直接在數(shù)據(jù)操作的 Observable 上注冊(cè)觀察者即可,相對(duì)于事件總線來(lái)說(shuō)是更精準(zhǔn)的(單線)的監(jiān)聽(tīng)。而事件總線的話則是更加松耦合的,出錯(cuò)的話會(huì)更加難排查,這里就不再展開(kāi)了。

Lambda

個(gè)人、團(tuán)隊(duì)喜好,代碼簡(jiǎn)潔了很多但是代碼的邏輯比較不好直觀理解了,原項(xiàng)目也只有 3 處代碼用到,故而去掉了。

此外,對(duì)于領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)中 Repository,原項(xiàng)目中把其實(shí)現(xiàn)放到了 data 層去實(shí)現(xiàn)(接口),造成 data 層會(huì)依賴其上一層(domain 業(yè)務(wù)層),作為分層架構(gòu)個(gè)人認(rèn)為不合適所以重新把它調(diào)整了。根據(jù) DDD,個(gè)人認(rèn)為 Repository 它的存在讓領(lǐng)域?qū)樱╠omain 業(yè)務(wù))感覺(jué)不到數(shù)據(jù)訪問(wèn)層的存在,它提供一個(gè)類似集合的接口提供給領(lǐng)域?qū)舆M(jìn)行領(lǐng)域?qū)ο蟮脑L問(wèn)。Repository 是倉(cāng)庫(kù)管理員,領(lǐng)域?qū)有枰裁礀|西只需告訴倉(cāng)庫(kù)管理員,由倉(cāng)庫(kù)管理員把東西拿給它,并不需要知道東西實(shí)際放在哪。

MVVM 理論簡(jiǎn)述

按照常理,先來(lái)說(shuō)基本概念:

Model,domain model(領(lǐng)域模型)或是數(shù)據(jù)層代表的數(shù)據(jù)模型,也可以理解為用戶界面需要顯示數(shù)據(jù)的抽象(數(shù)據(jù))

View, 應(yīng)用的界面

ViewModel,binder 所在之處,是 View 的抽象,對(duì)外暴露出公共屬性和命令,是 View 與 Model 的(綁定)連接器

此外還有必不可少的一部分:Binder,Android 中也就是 Data binding 了,提供 View 與 Model 的綁定功能。下面是結(jié)構(gòu)圖:

Android 中實(shí)現(xiàn)

目前 Android 的 data binding 還是 beta,還只是 one-way 單向綁定,功能上還有所欠缺、控制性也還不強(qiáng),但是把它寫出來(lái)還是沒(méi)問(wèn)題的。對(duì)于 Activity、Fragment 而言僅僅是作為 Java View 看待,與 XML 對(duì)應(yīng),所以里面只有 View 的展現(xiàn)邏輯,此外沒(méi)有其它代碼。一個(gè) Activity 或 Fragment(一般都 with XML) 對(duì)應(yīng)一個(gè) ViewModel,對(duì)于一個(gè)基礎(chǔ) View(XML)可以通過(guò)繼承對(duì)應(yīng)的 ViewModel 實(shí)現(xiàn)重用,本文的代碼也有體現(xiàn)。對(duì)于 Activity 和 Fragment 的View 狀態(tài)保存恢復(fù)也通過(guò) ViewModel 處理。因?yàn)?binding 的入口在 Activity 或 Fragment 中,所以為了方便寫個(gè)基類處理 ViewModel 和 Binding 的初始化,然后在 對(duì)應(yīng)的 XML 里加上 ViewModel 的 variable, XML 里不再有其它數(shù)據(jù)對(duì)象的 variable。

public abstract class BaseActivity extends Activity {

  private VM viewModel;
  private B binding;

  public void setViewModel(@NonNull VM viewModel) {
    this.viewModel = viewModel;
  }

  public VM getViewModel() {
    if (viewModel == null) {
      throw new NullPointerException("You should setViewModel first!");
    }
    return viewModel;
  }

  public void setBinding(@NonNull B binding) {
    this.binding = binding;
  }

  public B getBinding() {
    if (binding == null) {
      throw new NullPointerException("You should setBinding first!");
    }
    return binding;
  }

}

ViewModel 中通過(guò) ObservableField 來(lái)達(dá)到細(xì)粒度的控制,綁定操作都放在 ViewModel 里,然后 ViewModel 里可以有多個(gè) domain 中的 Interator(UseCase) 來(lái)得到 View 需要渲染的數(shù)據(jù) Model。對(duì)于 ObservableField 的綁定操作和命令操作(Command)都是暴露的,也易于測(cè)試。binding 現(xiàn)在缺少手動(dòng)在 Java 代碼中注冊(cè)通知事件的功能,比如有些 model 的渲染必須通過(guò) Java 代碼來(lái)操作的話就需要了,在 Activity(Java View) 中通過(guò)向 Binding 注冊(cè)通知回調(diào),而目前只能在 XML 中知道,當(dāng)然目前也可以自己實(shí)現(xiàn),方法也有多種:接口回調(diào)、EventBus、RxBus。。

架構(gòu)圖

除了 Persenter 改成 ViewModel 的邏輯、Repository 的抽象和具體都在 domain 外,其他部分基本一致,采用的測(cè)試也一致。

Clean Architecture:

MVVM_Clean-Architecture tier:

MVVM_Clean-Architecture put all:

Refactor

Talk is cheap. Show you the code. ↓↓↓
MVVM_Android-CleanArchitecture

需要注意的是 include 標(biāo)簽的 XML 節(jié)點(diǎn)中要使用到根節(jié)點(diǎn)中 data 標(biāo)簽里設(shè)置的 viewModel variable 的話需要這樣設(shè)置;

  

抽象類 ViewModel 中設(shè)置了 @Command 和 @BindView 注解,只起到清晰提醒作用。

具體重構(gòu)更改可以查看 commit 記錄:MVVM_Android-CleanArchitecture commits??梢钥吹?Activity 和 Fragment 的代碼是很清爽的,比 MVP 更清爽,因?yàn)?View 的數(shù)據(jù)渲染操作交給 binder 去處理了。對(duì) Activity 或其對(duì)應(yīng)界面進(jìn)行 UI 測(cè)試的話,Mock 出 model 代表的數(shù)據(jù)然后傳遞給 ViewModel 中 @BindView 暴露出的方法,然后檢驗(yàn)視圖對(duì)數(shù)據(jù)的正確顯示就行了,也就是 View 對(duì) Model 做了正確的渲染。

參考

企業(yè)應(yīng)用架構(gòu)模式
Architecting Android…The clean way? (Android-CleanArchitecture 的文章,譯文略)
Architecting Android…The evolution (Android-CleanArchitecture 的文章,譯文略)
Approaching Android with MVVM
ANDROID DATABINDING: GOODBYE PRESENTER, HELLO VIEWMODEL!

END

本文源碼:MVVM_Android-CleanArchitecture or Rocko-Android-Demo(-MVVM_Android-CleanArchitecture)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/11716.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<