文 |?Promise Sun
(注:本文是個(gè)人經(jīng)過學(xué)習(xí)之后胚迫,所做的一篇簡(jiǎn)單的筆記,并不涉及理論分析唾那,僅供快速記憶時(shí)參考访锻。)
一、MVC
M——對(duì)應(yīng)Model闹获,代表業(yè)務(wù)數(shù)據(jù)
V——對(duì)應(yīng)View期犬,代表視圖
C——對(duì)應(yīng)Controller,代表控制器
MVC架構(gòu)將視圖和數(shù)據(jù)分離避诽。在MVC模型里龟虎,Model不依賴于View,但是View是依賴于Model的沙庐。
優(yōu)點(diǎn):MVC 分層有助于管理復(fù)雜的應(yīng)用程序鲤妥;簡(jiǎn)化了分組開發(fā)佳吞。不同的開發(fā)人員可同時(shí)開發(fā)視圖、控制器邏輯和業(yè)務(wù)邏輯棉安。對(duì)于開發(fā)大型軟件來說更方便進(jìn)行模塊的劃分底扳,提高編碼速度與質(zhì)量。
缺點(diǎn):有一些業(yè)務(wù)邏輯在View里實(shí)現(xiàn)贡耽,導(dǎo)致要更改View比較困難衷模,至少那些業(yè)務(wù)邏輯是無法重用的。
二蒲赂、MVP
MVP:是基于MVC的阱冶。將MVC進(jìn)行升級(jí),對(duì)應(yīng)Android開發(fā)中就是幫助Activity解壓滥嘴。
mvp非常適合大型的APP開發(fā)木蹬。
M——(Model)?數(shù)據(jù)相關(guān)層,負(fù)責(zé)提供數(shù)據(jù)若皱。
V——(View) 視圖層镊叁,負(fù)責(zé)顯示。eg:Activity上的布局
P——(Presenter) 紐帶層是尖,用來連接Model與View意系。負(fù)責(zé)邏輯的處理泥耀。
Note:
Model層是真正處理數(shù)據(jù)的饺汹,Presenter是聯(lián)系M和V的中介,P持有M和V的引用痰催,P和V是雙向引用兜辞。
Model是一個(gè)獨(dú)立于Activity/Framgment用于保存數(shù)據(jù)的類。因?yàn)樗仟?dú)立于系統(tǒng)組件的夸溶,因此逸吵,不受系統(tǒng)生命周期的的影響。
核心:
把數(shù)據(jù)和業(yè)務(wù)邏輯從視圖層(View)剝離出來缝裁,V和P通過接口回調(diào)來通信扫皱。
優(yōu)點(diǎn):
1)可以進(jìn)行View的模擬測(cè)試。
MVP模式很適合測(cè)試捷绑,單獨(dú)測(cè)試VIEW成了一種可能韩脑。我們可以模擬View和Model的數(shù)據(jù)來測(cè)試Presenter的邏輯。
2)View與Model完全隔離粹污。
Model和View之間具有良好的松耦合設(shè)計(jì)段多,也就是說,如果Model或View中的一方發(fā)生變化壮吩,只要交互接口不變进苍,另一方就沒必要對(duì)上述變化做出改變加缘。使得Model層的業(yè)務(wù)邏輯具有很好的靈活性和可重用性。
這種分層思想在一定程度實(shí)現(xiàn)了解耦觉啊,符合類的單一職責(zé)設(shè)計(jì)原則拣宏。
3)Presenter與View的具體實(shí)現(xiàn)技術(shù)無關(guān)。
應(yīng)用程序可以用同一個(gè)Model層適配多種技術(shù)構(gòu)建的View層柄延。
Presenter與具體的View是沒有直接關(guān)聯(lián)的蚀浆,而是通過定義好的接口進(jìn)行交互,從而使得在變更View時(shí)候可以保持Presenter的不變搜吧,即重用市俊。
缺點(diǎn):
1)增加了代碼的復(fù)雜度,特別是針對(duì)小型Android應(yīng)用的開發(fā)滤奈,會(huì)使程序冗余摆昧。Presenter中除了應(yīng)用邏輯以外,還有大量的View->Model蜒程,Model->View的手動(dòng)同步邏輯绅你,會(huì)導(dǎo)致Presenter臃腫,維護(hù)困難昭躺。
2)內(nèi)存泄漏和空指針問題忌锯。由于P和V是互相引用,如果頁面銷毀時(shí)P還有正在進(jìn)行的任務(wù)领炫,那Activity無法回收偶垮,就發(fā)生了內(nèi)存泄漏。
(解決思路:在onDestroy()斷開引用關(guān)系帝洪,并取消網(wǎng)絡(luò)任務(wù)似舵。也可以通過弱引用來解決。)
3)P和V需要通過接口交互葱峡,還是存在一定耦合砚哗,算不上真正的解耦;如果接口有所變化的時(shí)候砰奕,需要改動(dòng)的地方太多;
MVC與MVP的不同:
1)MVP中Presenter取代了MVC中的Controller
2)MVC中Model蛛芥、View、Controller之間相互發(fā)生通信军援,而MVP中Model與Presenter相互通信仅淑,View與Presenter相互通信,而Model與View之間沒有通信盖溺。
3)MVC中Activity同時(shí)充當(dāng)了V和C的角色漓糙,這就屬于界限劃分不清楚。而MVP則劃分的很清楚烘嘱,Activity只充當(dāng)V的角色昆禽,業(yè)務(wù)邏輯控制交給了Presenter.
4)在MVP中View并不直接使用Model蝗蛙,它們之間的通信是通過Presenter(MVC中的Controller)來進(jìn)行的,所有的交互都發(fā)生在Presenter內(nèi)部醉鳖,而在MVC中View會(huì)直接從Model中讀取數(shù)據(jù)而不是通過Controller捡硅。
三、MVVM
MVVM:Model–View–Viewmodel
(參考網(wǎng)址:http://www.reibang.com/p/3651917c9b38)
是一種軟件架構(gòu)模式盗棵。是MVP的升級(jí)版壮韭。MVVM各個(gè)層職責(zé)單一,結(jié)構(gòu)清晰纹因,應(yīng)用可以很方便地進(jìn)行測(cè)試喷屋、維護(hù)和擴(kuò)展。
M——Model層瞭恰,數(shù)據(jù)模型(從服務(wù)器拉回來的JSON數(shù)據(jù))屯曹。主要負(fù)責(zé)數(shù)據(jù)的提供。
V——View層惊畏,視圖展示恶耽。View層是可以持有ViewModel的。
VM——ViewModel層颜启,主要負(fù)責(zé)業(yè)務(wù)邏輯的處理偷俭。ViewModel層不涉及任何的視圖操作。ViewModel層不持有View層的引用缰盏。這樣進(jìn)一步降低了耦合涌萤,View層代碼的改變不會(huì)影響到ViewModel層。
1)MVVM和MVP區(qū)別是vm和v是單向引用乳规,只有activity持有vm引用形葬,vm是不持有view的引用的合呐,所以vm的構(gòu)造方法中不能傳入視圖相關(guān)的對(duì)象暮的。這樣做,是為了防止生命周期問題導(dǎo)致的內(nèi)存泄漏淌实。
2)MVVM解決了MVP中接口繁雜冻辩、內(nèi)存泄漏等疑難雜癥。
3)結(jié)合Jetpack相關(guān)組件拆祈,MVVM效果會(huì)更好恨闪。
4)數(shù)據(jù)驅(qū)動(dòng)。在常規(guī)的開發(fā)模式中放坏,數(shù)據(jù)變化需要更新UI的時(shí)候咙咽,需要先獲取UI控件的引用,然后再更新UI淤年。獲取用戶的輸入和操作也需要通過UI控件的引用钧敞。在MVVM中蜡豹,這些都是通過數(shù)據(jù)驅(qū)動(dòng)來自動(dòng)完成的,數(shù)據(jù)變化后會(huì)自動(dòng)更新UI溉苛,UI的改變也能自動(dòng)反饋到數(shù)據(jù)層镜廉,數(shù)據(jù)成為主導(dǎo)因素。這樣MVVM層在業(yè)務(wù)邏輯處理中只要關(guān)心數(shù)據(jù)愚战,不需要直接和UI打交道娇唯,在業(yè)務(wù)處理過程中簡(jiǎn)單方便很多。
Note:
DataBinding是一個(gè)實(shí)現(xiàn)數(shù)據(jù)和UI綁定的框架寂玲,只是構(gòu)建MVVM模式的一個(gè)工具塔插。
MVVM可以根據(jù)項(xiàng)目的實(shí)際業(yè)務(wù)情況,結(jié)合AAC一起使用拓哟,效果會(huì)更好佑淀。
(注:以下為MVVM的故事,只做了解即可)
MVVM其實(shí)分為2個(gè)階段:在2017之前彰檬,是基于databinding的伸刃,在2017之后是基于AAC架構(gòu)的,也就是livedata逢倍、viewmodel相關(guān)捧颅。由于在2016、2017年Jetpack相關(guān)的Viewmodel较雕、LiveData還沒有推廣開碉哑,在2017之前要把數(shù)據(jù)從vm傳給v是比較麻煩,不用接口回調(diào)的話亮蒋,用觀察者模式來做是比較方便的扣典,但是那時(shí)候livedata還沒有出來,就只能用databinding的觀察者模式或自己手寫觀察者慎玖,由于這樣做比較麻煩贮尖,很多人甚至直接沿用接口回調(diào)去更新UI數(shù)據(jù)。正是由于當(dāng)時(shí)的技術(shù)和認(rèn)知不足以及很多誤導(dǎo)博客的廣泛傳播趁怔,導(dǎo)致了一部分人以為MVP+databinding就是MVVM了湿硝,這是一種錯(cuò)誤認(rèn)知。
四润努、AAC
AAC(全稱 Android Architecture Components)是谷歌在Google I/O 2017發(fā)布一套幫助開發(fā)者解決Android架構(gòu)設(shè)計(jì)的方案关斜。里面包含了兩大塊內(nèi)容:
1)生命周期相關(guān)的Lifecycle-aware Components
2)數(shù)據(jù)庫(kù)解決方案Room
優(yōu)點(diǎn):
使用 Android Architecture Components 提供的組件簡(jiǎn)化我們的開發(fā),能夠使我們開發(fā)的應(yīng)用模塊更解耦更穩(wěn)定铺浇,視圖與數(shù)據(jù)持久層分離痢畜,以及更好的擴(kuò)展性與靈活性。
提供的主要組件:
Lifecycle:管理組件生命周期
指的是 android.arch.lifecycle 包下提供的各種類與接口,可以讓開發(fā)者構(gòu)建能感知其他組件(主要指Activity 丁稀、Fragment)生命周期(lifecycle-aware)的類繁涂。
Lifecycle 使用兩個(gè)主要的枚舉類來表示其所關(guān)聯(lián)組件的生命周期:
Event 事件:從組件或者Lifecycle類分發(fā)出來的生命周期,它們和Activity/Fragment生命周期的事件一一對(duì)應(yīng)二驰。(ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY)扔罪;
State 狀態(tài):當(dāng)前組件的生命周期狀態(tài)(INITIALIZED, DESTROYED, CREATED, STARTED, RESUMED)。
Lifecycle的使用:
1)Lifecycle?提供的 LifecycleObserver桶雀,用以當(dāng) Activity 生命周期發(fā)生變化的時(shí)候主動(dòng)通知需求方矿酵。提供的LifecycleRegistry?類用于注冊(cè)和反注冊(cè)需要觀察當(dāng)前組件生命周期的 Observer。
2)LiveData是一個(gè)包含可以被觀察的數(shù)據(jù)載體矗积,基于觀察者模式實(shí)現(xiàn)全肮。
LiveData能夠感知組件(例如activities, fragments, services)的生命周期,防止內(nèi)存泄漏棘捣。
LiveData能夠在組件生命周期結(jié)束后自動(dòng)阻斷數(shù)據(jù)流的傳播辜腺,防止產(chǎn)生空指針等意外。
3)ViewModel 與 LiveData?結(jié)合使用乍恐,可以實(shí)現(xiàn)多處 UI?自動(dòng)更新评疗。
Room: 持久化數(shù)據(jù)結(jié)構(gòu)
Room 持久層庫(kù)提供了一個(gè)方便我們?cè)L問 SQLite 數(shù)據(jù)庫(kù)的抽象層(an abstraction layer ),幫助我們更好的在 APP 上創(chuàng)建我們的數(shù)據(jù)緩存茵烈,能夠讓 APP 即使在沒有網(wǎng)絡(luò)的情況也能正常使用百匆。
Note:
主要通過注解實(shí)現(xiàn)數(shù)據(jù)的增刪改查。
數(shù)據(jù)查詢可以返回 LiveData 數(shù)據(jù)呜投,通過 query 查詢返回的實(shí)體加匈,可以封裝成對(duì)應(yīng)RxJava 的操作符封裝對(duì)象,
使用到的主要注解:
@Entity(tableName = "orders") // 定義表名仑荐;
@PrimaryKey // 定義主鍵雕拼;
@ColumnInfo(name = "order_id") // 定義數(shù)據(jù)表中的字段名;
@Ignore // 指示 Room 需要忽略的字段或方法粘招;
@Embedded ?// 指定嵌入實(shí)體
@Query("SELECT * FROM orders") // 定義查詢數(shù)據(jù)接口啥寇;
@Insert // 定義增加數(shù)據(jù)接口;
@Delete // 定義刪除數(shù)據(jù)接口男图;
@Update // 定義更新數(shù)據(jù)接口示姿;
@Database // 定義數(shù)據(jù)庫(kù)信息甜橱,表信息逊笆,數(shù)據(jù)庫(kù)版本
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)點(diǎn)贊此文并注明出處岂傲,謝謝难裆!