您好,登錄后才能下訂單哦!
Android應(yīng)用開(kāi)發(fā)規(guī)模的擴(kuò)大,客戶端業(yè)務(wù)邏輯也越來(lái)越復(fù)雜,已然不是簡(jiǎn)單的數(shù)據(jù)展示了。如同后端開(kāi)發(fā)遇到瓶頸時(shí)采用的組件拆分思想,客戶端也需要進(jìn)行架構(gòu)設(shè)計(jì),拆分視圖和數(shù)據(jù),解除模塊之間的耦合,提高模塊內(nèi)部的聚合度。
開(kāi)始之前先上一張內(nèi)部分享時(shí)用的PPT圖:
以上是筆者在客戶端開(kāi)發(fā)過(guò)程中面臨的問(wèn)題,涉及到以下四個(gè)主題:
Android App的架構(gòu)設(shè)計(jì):從VM、MVC、MVP到MVVM
Android App的網(wǎng)絡(luò)訪問(wèn):支持REST、HTTPS及SPDY的Retrofit+Okhttp
Android App的響應(yīng)式編程:RxJava/RxAndroid解決方案
Android App的依賴注入:Dagger2和ButterKnife使用
本文將從架構(gòu)設(shè)計(jì)入手,分享筆者在Android開(kāi)發(fā)中采用MVC、MVP及MVVM的一些想法。
Android原生開(kāi)發(fā)采用XML文件實(shí)現(xiàn)頁(yè)面布局,通過(guò)Java在Activity中開(kāi)發(fā)業(yè)務(wù)邏輯,這種開(kāi)發(fā)模式實(shí)際上已經(jīng)采用了MVC的思想,分離視圖和控制器。MVC模式(Model–view–controller)是軟件工程中的一種軟件架構(gòu)模式,把軟件系統(tǒng)分為三個(gè)基本部分:模型(Model)、視圖(View)和控制器(Controller)。
MVC模式最早由Trygve Reenskaug在1978年提出,是施樂(lè)帕羅奧多研究中心(Xerox
PARC)在20世紀(jì)80年代為程序語(yǔ)言Smalltalk發(fā)明的一種軟件架構(gòu)。MVC模式的目的是實(shí)現(xiàn)一種動(dòng)態(tài)的程序設(shè)計(jì),使后續(xù)對(duì)程序的修改和擴(kuò)展簡(jiǎn)化,并且使程序某一部分的重復(fù)利用成為可能。除此之外,此模式通過(guò)對(duì)復(fù)雜度的簡(jiǎn)化,使程序結(jié)構(gòu)更加直觀。軟件系統(tǒng)通過(guò)對(duì)自身基本部分分離的同時(shí)也賦予了各個(gè)基本部分應(yīng)有的功能。專業(yè)人員可以通過(guò)自身的專長(zhǎng)分組:
控制器(Controller)- 負(fù)責(zé)轉(zhuǎn)發(fā)請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理。
視圖(View) - 界面設(shè)計(jì)人員進(jìn)行圖形界面設(shè)計(jì)。
模型(Model) - 程序員編寫(xiě)程序應(yīng)有的功能(實(shí)現(xiàn)算法等等)、數(shù)據(jù)庫(kù)專家進(jìn)行數(shù)據(jù)管理和數(shù)據(jù)庫(kù)設(shè)計(jì)(可以實(shí)現(xiàn)具體的功能)。
——以上內(nèi)容來(lái)自《維基百科》
在Android編程中,View對(duì)應(yīng)xml布局文件,Model對(duì)應(yīng)實(shí)體模型(網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、I/O),Controller對(duì)應(yīng)Activity業(yè)務(wù)邏輯,數(shù)據(jù)處理和UI處理。如下圖所示。
但在實(shí)際開(kāi)發(fā)過(guò)程中,純粹作為View的各個(gè)XML文件功能較弱,Activity基本上都是View和Controller的合體,既要負(fù)責(zé)視圖的顯示又要加入控制邏輯,承擔(dān)的功能很多,導(dǎo)致代碼量很大。所有更貼切的目前常規(guī)的開(kāi)發(fā)說(shuō)應(yīng)該是View-Model模式,大部分都是通過(guò)Activity的協(xié)調(diào),連接處理邏輯的。
在業(yè)務(wù)邏輯稍微復(fù)雜一點(diǎn)的頁(yè)面,Activity的代碼超過(guò)一千是很容易的,如果作者又剛好讀過(guò)《如何寫(xiě)出無(wú)法維護(hù)的代碼》,那么恭喜后來(lái)接手該代碼的童鞋,接下來(lái)的幾個(gè)月會(huì)很酸爽的。。。
既然Activity存在代碼量過(guò)大的問(wèn)題,那自然會(huì)想到進(jìn)行拆分。上節(jié)說(shuō)到Android原生開(kāi)發(fā)采用了MVC的思想,但Activity并不是一個(gè)標(biāo)準(zhǔn)的MVC模式中的Controller,它的首要職責(zé)是加載應(yīng)用的布局和初始化用戶界面,并接受并處理來(lái)自用戶的操作請(qǐng)求,進(jìn)而作出響應(yīng)。隨著界面及其邏輯的復(fù)雜度不斷提升,Activity類的職責(zé)不斷增加,以致變得龐大臃腫。
MVP是從MVC過(guò)渡而來(lái),MVP框架由三部分組成:View負(fù)責(zé)顯示,Presenter負(fù)責(zé)邏輯處理,Model提供數(shù)據(jù)。Android開(kāi)發(fā)從MVC過(guò)渡到MVP,最主要的變化就是將Activity中負(fù)責(zé)業(yè)務(wù)邏輯的代碼移到Presenter中,Activity只充當(dāng)MVP中的View,負(fù)責(zé)界面初始化以及建立界面控件與Presenter的關(guān)聯(lián)。
這樣拆分之后,Presenter承擔(dān)了大量的邏輯操作,避免了Activity的臃腫。整個(gè)架構(gòu)如下圖所示。
View(Activity)負(fù)責(zé)響應(yīng)用戶操作,通過(guò)Presenter暴露的方法請(qǐng)求數(shù)據(jù);
Presenter在獲取數(shù)據(jù)后,通過(guò)View(Activity)暴露的方法實(shí)現(xiàn)界面控制(showLoading/showUsers);
Presenter的數(shù)據(jù)是通過(guò)Model來(lái)獲取的,Model包含網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)以及I/O等;
Model通過(guò)回調(diào)的方式將數(shù)據(jù)傳到Presenter中。
采用MVP明顯的優(yōu)點(diǎn)是避免了傳統(tǒng)開(kāi)發(fā)模式中View和Model耦合的情況,提高了代碼可擴(kuò)展性、組件復(fù)用能力、團(tuán)隊(duì)協(xié)作的效率以及單元測(cè)試的便利性。但也有一些缺點(diǎn),比如:
Model到Presenter的數(shù)據(jù)傳遞過(guò)程需要通過(guò)回調(diào);
View(Activity)需要持有Presenter的引用,同時(shí),Presenter也需要持有View(Activity)的引用,增加了控制的復(fù)雜度;
MVC中Activity的代碼很臃腫,轉(zhuǎn)移到MVP的Presenter中,同樣造成了Presenter在業(yè)務(wù)邏輯復(fù)雜時(shí)的代碼臃腫。
MVVM是Model-View-ViewModel的簡(jiǎn)稱,從實(shí)際效果來(lái)看,ViewModel是View的數(shù)據(jù)模型和Presenter的結(jié)合,具體結(jié)構(gòu)如下圖所示:
View(視圖層)采用XML文件進(jìn)行界面的描述;
Model(模型層)通過(guò)網(wǎng)絡(luò)和本地?cái)?shù)據(jù)庫(kù)獲取視圖層所需數(shù)據(jù);
ViewModel(視圖-模型層)負(fù)責(zé)View和Model之間的通信,以此分離視圖和數(shù)據(jù)。
View和Model之間通過(guò)Android Data Binding技術(shù),實(shí)現(xiàn)視圖和數(shù)據(jù)的雙向綁定;ViewModel持有Model的引用,通過(guò)Model的方法請(qǐng)求數(shù)據(jù);獲取數(shù)據(jù)后,通過(guò)Callback(回調(diào))的方式回到ViewModel中,由于ViewModel與View的雙向綁定,使得界面得以實(shí)時(shí)更新。同時(shí),界面輸入的數(shù)據(jù)變化時(shí),由于雙向綁定技術(shù),ViewModel中的數(shù)據(jù)得以實(shí)時(shí)更新,提高了數(shù)據(jù)采集的效率。
采用ViewModel解決MVP中View(Activity)和Presenter相互持有對(duì)方應(yīng)用的問(wèn)題,界面由數(shù)據(jù)進(jìn)行驅(qū)動(dòng),響應(yīng)界面操作無(wú)需由View(Activity)傳遞,數(shù)據(jù)的變化也無(wú)需Presenter調(diào)用View(Activity)實(shí)現(xiàn),使得數(shù)據(jù)傳遞的過(guò)程更加簡(jiǎn)潔,高效。
在Android中實(shí)現(xiàn)MVVM架構(gòu)的核心支撐技術(shù)是Google去年I/O大會(huì)開(kāi)源的Data binding技術(shù),這項(xiàng)技術(shù)的思想并不新穎,最初由微軟提出,在前端開(kāi)發(fā)中已經(jīng)有成熟的應(yīng)用。下面對(duì)其進(jìn)行簡(jiǎn)要的介紹。
學(xué)習(xí)Data Binding主要推薦兩個(gè)內(nèi)容:
官方的Data Binding教程
精通 Android Data Binding
這兩篇文章中已經(jīng)將Data Binding的基本內(nèi)容描述的很詳細(xì)了。這里僅列兩個(gè)在實(shí)踐中遇到的坑,拋磚引玉。
ObservableField的get方法可能無(wú)法返回界面實(shí)時(shí)更新的內(nèi)容
public ObservableField<String> username = new ObservableField<>();
上述username表示用戶名,在界面上可能會(huì)與EditText綁定。通過(guò)username的set方法可以設(shè)置EditText顯示,但如果輸入變更后,通過(guò)get方法卻不一定能及時(shí)返回界面的數(shù)據(jù)。
Data Binding依然有很多支持的不好的組件(listview,recyclerView等),不可能通過(guò)給所有組件綁定ViewModel從而實(shí)現(xiàn)Activity沒(méi)有業(yè)務(wù)邏輯操作。另外,ViewModel獲取數(shù)據(jù)之后,也不可能把所有數(shù)據(jù)直接綁定到界面,有些也需要通過(guò)回調(diào)傳到Activity中。
從MVC、MVP到MVVM,實(shí)際上是模型和視圖的分離過(guò)程。MVC中模型和視圖沒(méi)有完全分離,造成Activity代碼臃腫,MVP中通過(guò)Presenter來(lái)進(jìn)行中轉(zhuǎn),模型和視圖徹底分離,但由于V和P互相引用,代碼不夠優(yōu)雅。ViewModel通過(guò)Data Binding實(shí)現(xiàn)了視圖和數(shù)據(jù)的綁定,解決了這種MVP的缺陷,但目前也存在Data Binding還不成熟的問(wèn)題。
其實(shí),MVC、MVP及MVVM沒(méi)有絕對(duì)好壞,在軟件編程過(guò)程中,也沒(méi)必要非此即彼,最重要的是讓軟件高內(nèi)聚、低耦合、可維護(hù)、可擴(kuò)展,至于架構(gòu),根據(jù)實(shí)際情況選擇吧。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。