前言
大家好,我是《Jetpack MVVM 精講》的獨立原創作者 KunMinX,GitHub star 8.7k,專注于深度思考和 Jetpack MVVM 的分享。
關于 MVP 和 MVVM 本質和區別的文章,本來我是不想寫的,因為經過長達一年的耳濡目染 和對方法論的試煉,相信 但凡沉下心閱讀過《重學安卓》體系化文章的讀者,多已練就 透過表象迅速抓住本質 的稀缺能力。
專欄每天都有新的讀者加入,然而沒想到的是,1 年了,仍然時不時的會被咨詢、或是在各個社區看到人們眾說紛紜地在談論 MVP 和 MVVM 誰“好”誰“壞”。
并不是每一個提問都值得被回答
愛因斯坦說,“提出正確的問題,問題就已解決了一半”。
換言之,并不是每一個提問都值得被回答。一次提問所包含的信息量,其實遠遠超出內容本身。
透過提問者的提問,幾乎可以瞬間感知到,提問者對事實狀況的掌握程度,并由此來決定到底值不值得繼續交流。
與“高”質量提問者的交流 讓人感到如沐春風 —— 幾句話就能自己先把背景交代清楚,然后就某個細節提出自己的困惑 —— 這讓我不免想要與之多聊幾句,把我知道的毫無保留地分享出去。
反之,“低”質量提問 讓人感到 不舒服,甚至不對勁 —— 明明不遺余力地在多處 劃重點 反復交代,明明白紙黑字寫得清清楚楚,甚至段落、鏈接給他指出來,卻視而不見,就好像從未發生過。
注:我從不在技術交流中使用 “高”、“低”、“好”、“壞”、“輕”、“重” 之類的主觀描述,此處只是以多數人方便理解的方式來介紹。文中使用到的主觀描述一律加上雙引號。
更有甚者,為了滿足抬杠的快感,不惜浪費彼此的時間 ...
本質和區別,我只說一遍
事實上,我并不會去判斷來者是否是來抬杠,而只須透過對方所說的話,即可瞬間判斷對方說的是事實,還是自顧自地扯淡 —— 你沒法和一個前來扯淡的人交流,你會發現 這種對話往往 存在巨大的代溝,并且抬杠者無意謀求和縫合對事實的理解,他本來就是為了 “來的快” 的精神勝利而來。
事實即 "就事論事",事實必有特定背景和目的來約束。一切脫離事實特征的意見和觀點都是瞎扯淡,沒有討論的前提、不值得參與 —— ?KunMinX
所以,本文只寫給那些 真的想搞清楚事實 的有緣人,只為有緣人鋪路。
并且關于 MVP 和 MVVM 各自的本質及區別,我就只說這么一遍,所以請認真閱讀。
文章目錄一覽
- 前言
- 并不是每一個提問都值得被回答
- 本質和區別,我只說一遍
- 先說結論
- 所以二者的區別是什么?
- Jetpack MVVM 和 MVVM 模式的關系
- 我為什么能瞬間感知溝通質量的 “好” 與 “壞” ?
- 綜上
先說結論
MVP 本質:是廣義上的架構模式,適用于面向實體或虛擬用戶接口的開發。
它主要是在 MVC 的背景下,通過 依賴倒置,來解決 邏輯復用 難、實現更替 難 的問題。
MVVM 本質:是狹義上的架構模式,專用于頁面開發。
它主要是在多人協作的軟件工程的背景下,通過只操作 ViewModel 中映射的視圖數據 來刷新視圖狀態,以此來解決 視圖調用的一致性問題 從而規避不可預期的錯誤。
所以二者的區別是什么?
區別就在于:
一個是廣義上的架構:
你可以通過同一套邏輯去驅動不同品牌設備的實體用戶接口(比如不同品牌的耳機線控),或虛擬用戶接口(比如 Android 視圖,但存在一致性問題而不推薦);
一個是狹義上的架構:
專用于可視化頁面的開發,通過解決一致性問題 來規避不可預期的錯誤。
所以輕易地你就可發現,二者分別適用于 在各自的專場下 解決不同的問題,根本沒有可比性,更沒有所謂的 誰“好”誰“壞” 之分。
而且除了沒有可比性,二者之間其實也沒任何關系,MVP 的特質是 依賴倒置,MVVM 的特質是 數據驅動,二者沒有說誰演化自誰的關系。回到剛剛所說的:“根本就是 特定場景下解決特定問題 的兩種截然不同的架構模式”。
沒有所謂的 MVVM == MVP + DataBinding,正如沒有所謂的 雷峰塔 == 雷鋒 + 塔。
Jetpack MVVM 和 MVVM 模式的關系
Jetpack MVVM 是 MVVM 模式在 Android 開發中的一個具體落實,也即它不僅僅包含了 MVVM 模式用于解決 “視圖調用的一致性問題” 這一本質,還兼顧了 Android 頁面開發中其他不可預期的錯誤。
正如我在《 Jetpack MVVM 精講》中介紹到的:
Lifecycle 的存在,主要是為了解決 生命周期管理 的一致性問題。
LiveData 的存在,主要是為了幫助 新手老手 都能不假思索地 遵循 通過唯一可信源分發狀態 的標準化開發理念,從而在快速開發過程中 規避一系列 難以追溯、難以排查、不可預期 的問題。
ViewModel 的存在,主要是為了解決 狀態管理 和 頁面通信 的問題。
DataBinding 的存在,主要是為了解決 視圖調用 的一致性問題。
它們的存在 大都是為了 在軟件工程的背景下 解決一致性的問題、將容易出錯的操作在后臺封裝好,方便使用者快速、穩定、不產生預期外錯誤地編碼。
所以,Jetpack MVVM 的高頻核心架構組件,和 iOS、WPF 的實現一定是有區別的,只不過抓住本質,我們就能舉一反三,以不變應萬變。
通過《事關軟件工程安全 的 數據驅動 UI 框架 掃盲干貨》一文的介紹我們可知,DataBinding 的唯一挑戰者是 基于函數式編程的數據驅動 UI 框架,也即發源自前端 Elm 框架的 React、Flutter、Jetpack Compose、SwiftUI 之流。
所以 React、Flutter 這種,算不算 MVVM 呢?其實也算。DataBinding 被換下了,但視圖調用一致性問題有函數式編程來解決。
所以 ...
我為什么能瞬間感知溝通質量的 “好” 與 “壞” ?
事實上,在 “先說結論” 一節介紹完本質后,按照慣例,我是會以 “如果這樣說還沒有理解的話” 來引出下文,開始交代 “Before” 和 “After” 的,
因為每天都有新的讀者加入,為方便新讀者能夠 結合自己的興趣 隨機閱讀,專欄幾乎每一篇文章 都是以獨立專輯的完整度來發行。
這也是為什么,我的每一篇文章,都當做自己是第一次和讀者見面、不遺余力地貫徹 全網獨家的深度思考寫作風格,讓每一位新讀者都有機會和我注入到文章的靈魂發生交流。
然而這一次,我不得不小小地任性一把,因為如果上述這樣說了一通,還是不理解的話,答案早就寫在以下幾篇里:
《是 持續增量更新 的 背景緣由甜點》 的 “飯后甜點不能當主食吃” 一節 (推薦);
《基本功:是隨時隨地可受用的 深度思考秘訣》 的 “所以如何正確地思考” 一節;
《這是一份 簡潔有力的 認知地圖》 的 “認知地圖” 一節;
還有近期在掘金開源的《獨家解析 | Android 深度思考寫作技巧》 的 “公式” 一節 ——
這幾處都有 就正確的思維方式 提供方法論依據 以及手把手示范。
一旦熟悉了這套方法論,那些沒完沒了的爭論,你會不會參與?我想大概率不會,因為你一眼就看出 這些言論中不包含基于事實的思考,不過是 憑主觀感覺、個人喜好 的自說自話。
參與到這種扯淡中 是對自己的不尊重,所以你不會參與。
綜上
MVP 的本質是對 MVC 的依賴倒置,借此來解決 邏輯復用難 以及 實現替換難 的問題,
因為在 MVP 下,UI 邏輯和業務邏輯全在 Presenter 中寫,UI 和 Model 的實現,可以隨意替換,
也即如上文介紹的,通過同一套 Presenter 中的邏輯,可以驅動不同品牌不同型號的耳機的線控。(注意 UI 的全稱是 “用戶接口”,臺灣的術語更準確,叫 “用戶介面”。UI 不是狹義上的頁面,UI 就是 UI)
MVVM 的本質是對 View 數據的映射,借此來在軟工背景下解決 視圖調用的一致性問題。
MVP 和 MVVM 二者的區別在于,前者是廣義的架構模式,普遍適用;后者是狹義上的架構模式,專用于頁面開發,可以解決例如 視圖調用的一致性問題,來規避不可預期的錯誤。
也即 MVP 和 MVVM 本質上毫無關系,沒有誰演化自誰。
Jetpack MVVM 是 MVVM 模式在 Android 下的一個落地,也即除了解決 視圖調用的一致性問題,還因地制宜地解決了其他一致性問題,從而規避各種不可預期的錯誤,讓軟件開發的工作得以完成得又快又好。
這樣說,你理解了嗎?
版權聲明
本文以 CC 署名-非商業性使用-禁止演繹 4.0 國際協議 發行。
Copyright ? 2019-present KunMinX
文中提到的 關于 “MVP 和 MVVV 各自的本質及區別” 的具體描述、“用戶介面與耳機線控” 的舉例、架構設計圖例、“DataBinding 與函數式編程數據驅動框架的關系” 的具體描述、“Jetpack MVVM 和 MVVM 關系” 的描述、“Lifecycle、LiveData、ViewModel、DataBinding 等架構組件的存在意義”、“通過解決一致性問題來規避不可預期的錯誤” 等多處 對特定現象及其本質的概括,均屬于本人獨立原創的成果,本人對此享有所有權和最終解釋權。
當您借鑒或引用本文的引言、思路、結論進行二次創作,或全文轉載時,須注明鏈接出處,否則我們保留追責的權利。