模式
談MVP之前我們先來聊一聊軟體開發中的模式,在軟體開發中由於需求的不斷變更,產品的不斷迭代,程式設計師們為了應付產品經理不斷變化的需求,提出了一系列的定式。定式一詞最早應該是來源於圍棋中的術語,圍棋的定式本質上也就是通過一定開局方式來提高圍棋的勝率,軟體開發中也是一樣的,通過精心設計的一系列定式,來解決軟體開發中反覆遇到的一些問題,來快速響應產品需求。
關於“模式”在開發中會會提及兩個詞,設計模式和架構模式,兩者是有區別的,我的理解是:設計模式更加關注於微觀,架構模式更加關注於巨集觀設計。往往都是架構模式針對的是整個產品層面的設計,設計模式針對的是產品中的某一個功能點的設計,比較常見的MVC和MVP就屬於巨集觀架構模式,觀察者和模板模式就屬於微觀設計模式。當然也不是絕對的,設計模式中也可能具有巨集觀架構,架構模式中也可能有微觀架構,不過從並集結構來看,大體如此。
架構模式的設計更加註重於產品業務層面的考慮,常見的框架模式有如下幾種:
- 分層模式
- 微模式
- 事件驅動
- 基於空間架構
當然,在實際設計中可能會有多種框架設計方式結合一起。關於設計模式和架構模式,推薦兩本書,GOF的《設計模式》和Frank Buschmann的《面向模式的軟體設計》。
分層思維和MVC模式
MVC模式本質上就是屬於框架模式中的分層架構,分層架構其實就是模仿自然界各司其職的思維方式,這種思維在網際網路公司的組織架構中尤其明顯,產品經理負責功能規劃,軟體開發工程師負責開發出對應功能,測試人員保證軟體質量。網路協議也是一個著名的分層思想 :
Java EE是一個天然的MVC分層架構
- 檢視View: JSP檔案負責顯示,直接和使用者打交道
- 控制器Controller:一般是一個servlet,完成業務邏輯處理,並伴隨著請求Model層資料
- 模型層Model:表現在Java EE中就是一些bean以及持久化資料邏輯。Model層可以直接將資料傳送給View,通知View重新渲染資料
MVC優缺點網上有很多人談,比如MVC具有低耦合性,高內聚性、可維護性強等等,缺點是需要新建的類非常多,C層快速膨脹等等。但是這些都不是致命的缺點,真正致命的缺點後面再談。
為什麼是MVP而不是MVC?
下圖直觀的顯示了MVP和MVC的區別:
幾句話來區分一下MVP和MVC:
- 用P層替代了C層
- P層和V層之間通過一層介面來進行解耦
- V層和M層不會直接通訊,通訊僅僅侷限於V和P之間
MVP和MVC比有什麼好處?一句話來說:
增加了中心節點,減少了資料流向的混亂
明顯,P層就是MVP種的中心節點,中心節點有什麼好處?
令行禁止,說一不二
所有的資料都從P層流入,流出,資料流向透明、可控,MVC具有的一優點MVP都有,而MVC由於缺少中心化的資料控制層,所以V層可以直接和M層通訊,導致資料的流入和流出一團糟,這個就是MVC的致命缺點之一,它本身違背了分層思想中的分層隔離的思想。
Android開發中為什麼MVC不好使,一個原因是Android本身就不是一個天然的MVC架構,它只是一個類MVC架構,M層是資料層,C層是Activity/fragment,V是XML檔案,XML的生命週期又需要依賴於Activity/fragment,所以在Activity/fragment中會有對View的操作。 另外一個原因是MVC在Android開發中的侷限,V層會經常對M層做通訊,比如V層中接收M層資料的變化,重新整理頁面,這種直接M直接作用於V;有時候可能C層也會直接通知V層來響應資料的變化,如果出現BUG,你很難找到是哪一個部分導致的.而MVP模式通過把邏輯縮到P層,通過在View和presenter之間增加一層介面,而減少model和view層的互動,從而把部分邏輯完全轉接給presenter層,進一步減少了View層的邏輯,這樣依賴View能夠真正的做到完全處理UI方面的工作.
- 降低耦合度:MVP減少了MVC模式下V和C的直接互動,進一步減少了V層的邏輯處理.讓V層變的非常薄,P層變的很厚.
- 增加V層和P層直接之間的介面,讓P層可以直接操作V層UI,把邏輯完全轉嫁給P層處理
- Activity 只處理生命週期的任務和View層的邏輯
- Presenter層被抽象稱介面,便於進行單元測試
- 減少記憶體洩漏的風險,因為非同步任務完全抽象稱了介面,減少了相互之間的引用
優點說完了,缺點也同樣明顯。MVP的中中心化的問題在於中心節點承載過多的邏輯,導致P層不斷臃腫,特別是在Android開發中,網路請求、資料庫操作、控制邏輯等等,P層邏輯不斷增加,最後出現了一個巨型的上帝類。
這個時候你需要一個工具,去簡化P層程式碼。
RxJava
RxJava正是這個工具。RxJava是什麼,簡單來說:
RxJava讓你通過事件流的方式來對資料進行操作,這種操作包括資料的組合、包裝、監聽,並且讓你在同步和非同步執行緒中自如切換。
關於RxJava更多介紹,點選這裡
RxJava在MVP中起到的作用:
通過對事件流的操作,減化P層的邏輯,減少程式碼的耦合
怎麼減少?
- 非同步操作的簡便性,徹底拋棄各種地獄回撥
- 徹底訣別坑爹的AnsyTask
一句話來說:
越是複雜的邏輯,越能體現RxJava的優越性
更多關於RxJava的學習參考其它教程。
MVP的工程實踐
MVP的實踐基本是基於谷歌官方的架構
具體工程實踐下一篇在講。
總結
軟體架構永遠是服務於業務的,業務的複雜度決定了架構的簡潔性,在很多時候,架構不是萬能的,在無法用架構解決情況下,考慮對業務做精簡和分層能夠達到很好的效果。MVC架構在分層架構中是佔有非常重要的地位,不過由於MVC本身的缺點和Android自身架構的侷限性,原生的MVC在Android應用會有非常多的問題,而MVP架構的分層+中心化的架構模式能夠在Android的專案中取得良好的效果。