在上篇文章里,我們對(duì)Google官方的TODO-MVP-Loaders做了分析,今天繼續(xù)探討另外一種官方實(shí)現(xiàn),基于Clean架構(gòu)的MVP實(shí)現(xiàn)。
Clean架構(gòu),如果從分層方式來(lái)看,主要涉及了一種“洋蔥式”的分層設(shè)計(jì),這些層次包括:UI框架層、Presenter層、Domain層、Entities層。
各層之間是單向的、從外到內(nèi)的依賴關(guān)系,并且越往內(nèi)層,其實(shí)現(xiàn)越不依賴于具體的平臺(tái)框架。更專業(yè)、更詳細(xì)的說(shuō)明,可直接閱讀Uncle Bob的文章:The Clean Architecture。
這種架構(gòu)的好處有:
1、當(dāng)UI相關(guān)代碼需要修改時(shí),對(duì)其他層不產(chǎn)生影響或者影響很少;
2、業(yè)務(wù)邏輯通過(guò)UseCase或者Interactor類封裝,方便擴(kuò)展維護(hù);
3、可以靈活使用不同的數(shù)據(jù)庫(kù)方案,而不影響其他部分代碼;
4、方便單元測(cè)試,提前暴露問(wèn)題。
上述分層方式與MVP的分層架構(gòu)有所不同,但兩者可以結(jié)合起來(lái),發(fā)揮各自的優(yōu)點(diǎn)。我們來(lái)看TODO-MVP-Clean是如何實(shí)現(xiàn)的。
這是Google官方網(wǎng)站上,對(duì)應(yīng)TODO-MVP-Clean實(shí)現(xiàn)的一幅圖。
從上圖可以看出,相對(duì)于基礎(chǔ)實(shí)現(xiàn),主要是增加了Domain層,包括與具體業(yè)務(wù)邏輯對(duì)應(yīng)的UseCase及其派生類。
在官方介紹里面,該實(shí)現(xiàn)從整體上被分為了3層:
Presentation Layer,包括各種View、Presenter類;
Domain Layer,包括UseCase及其派生類;
Data Layer,主要包括實(shí)現(xiàn)了TasksDataSource接口的TasksRepository類。
其UML靜態(tài)結(jié)構(gòu)圖如下。這里為了簡(jiǎn)潔,只選取了其中保存任務(wù)相關(guān)的靜態(tài)結(jié)構(gòu)進(jìn)行分析,對(duì)于其他諸如獲取任務(wù)、刪除任務(wù)的結(jié)構(gòu)分析也類似。
以新建任務(wù)時(shí)的保存操作為例,其UML動(dòng)態(tài)序列圖如下。
結(jié)合序列圖,我們?cè)趨⒖荚搶?shí)現(xiàn)時(shí),可以關(guān)注如下幾點(diǎn)。
首先是業(yè)務(wù)邏輯相關(guān)調(diào)用。在Presenter中,原先基礎(chǔ)實(shí)現(xiàn)里面直接調(diào)用TaskRepository對(duì)象的地方,在該實(shí)現(xiàn)中,已經(jīng)改為通過(guò)UseCaseHandler調(diào)用,再由內(nèi)部的UseCaseThreadPoolScheduler調(diào)用SaveTask這個(gè)UseCase的具體實(shí)現(xiàn),最后通過(guò)TaskRepository的saveTask方法來(lái)完成整個(gè)操作。
其次關(guān)注回調(diào)處理。在SaveTask里面,保存成功后,會(huì)調(diào)用UseCaseHandler中的onSuccess回調(diào)函數(shù),再通過(guò)UseCaseThreadPoolScheduler觸發(fā)AddEditTaskPresenter中的回調(diào)。這里和具體業(yè)務(wù)邏輯相關(guān)的地方,分別在SaveTask、AddEditTaskPresenter中。
再次就是Domain層的UseCase里面模板參數(shù)的實(shí)現(xiàn)。還是以保存任務(wù)為例,在定義SaveTask類時(shí),需要根據(jù)具體業(yè)務(wù)(例如保存任務(wù)數(shù)據(jù)),專門定義內(nèi)部類,分別實(shí)現(xiàn)模板參數(shù)中UseCase.RequestValues和UseCase.ResponseValue這兩個(gè)接口。
另外,UseCaseThreadPoolScheduler里面的線程池設(shè)計(jì),用于同時(shí)有多個(gè)UseCase需要執(zhí)行的場(chǎng)景。這里還使用了單例模式,上述Scheduler所屬的UseCaseHandler對(duì)象為全局的單例對(duì)象。