MVC/MVP/MVVM
架構模式的文章很多,好理解的沒有幾個。大部分文章出現的主要問題有:
-
沒有設定好作用域:前端MVC是改造過的MVC,和後臺MVC有明顯的區別,不能一概而論
-
沒有實際的例子:實際的例子對應日常的工作,沒有就很難產生共鳴,從而造成看一次忘一次的困擾。
-
沒有明確的目的:理解架構模式的真正意義是什麽?虛擬DOM和組件化在MV*中的位置?
題目開的太大,一定有疏忽錯誤的地方,也歡迎大家指出~
1.1 後端MVC與前端MVC
從實現上來說,主要可以分為後端MVC和前端MVC兩種。這兩種MVC的不同點如下:
可以看到,前端的MVC其實是為了解決前端復雜JS模塊化的問題,從後端MVC的V分出來的MVC
1.2 MVC / MVP / MVVM
可以清晰的看出,這三個架構的區別在“M與V聯系”的部分。下面我們針對這一部分做一個對比:
-
Controller:負責監聽View的用戶事件,得到數據後Controller做一些處理,然後渲染View。
當然,在一些後端MVC架構裏,Model也可以直接渲染View模版,但這只是不同變種的實現,這裏不多做討論。
但是隨時邏輯的復雜,這樣的處理遇到了很難調試的問題。由於View一定要運行在UI環境下,而且Model或者Controller和View強耦合,沒有辦法單獨驗證應用邏輯的正確性。當出了問題之後,因為各個模塊是耦合在一起的,也不能快速判斷究竟是哪個模塊出現的問題。因此,MVP模式出現了。
-
Presenter: 比起Controller,Presenter會調用View層提供的接口去渲染Model。這樣做有幾點好處:
-
面向接口編程
-
更好的解耦
-
方便做單元測試
現在P和V解耦了,P可以自己做單元測試了。軟件結構劃分的更加清楚,邏輯清晰並方便調試。但是這一切都來自於一個前提:View層要提供接口。當一個UI復雜起來的時候,View層需要提供的接口是很多的,這本身也是一種開發調試的成本。所以,MVVM應運而生。
-
ViewModel:比起MVP中View需要自己提供API,MVVM在VM中構建一組狀態數據(state data),作為View狀態的抽象。然後通過雙向數據綁定(data binding)使VM中的狀態數據(state data)與View中的顯示狀態(screen state)保持一致。這樣,VM中的展示邏輯只需要修改對應的狀態數據,就可以控制View的狀態,從而避免在View上開發大量的接口。
VM有沒有什麽缺點?有的,當UI比較簡單的時候,使用VM就會使業務邏輯變得復雜,有過分設計的嫌疑。所以VM只適合復雜UI交互的項目。
2. 舉個例子
例子:現在用戶下拉刷新一個頁面,頁面上出現10條新的新聞,新聞總數從10條變成20條。那麽MVC、MVP、MVVM的處理依次是:
1. View獲取下拉事件,通知Controller
2. Controller向後臺Model發起請求,請求內容為下拉刷新
3. Model獲得10條新聞數據,傳遞給Controller
4. Controller拿到10條新聞數據,可能做一些數據處理,然後拿處理好的數據渲染View
MVC: 拿到UI節點,渲染10條新聞
MVP: 通過View提供的接口渲染10條新聞
MVVM: 無需操作,只要VM的數據變化,通過數據雙向綁定,View直接變化
3. 了解架構的意義
最大的意義是站在創造者的角度上去思考問題,他們為什麽要這麽設計,這樣做又有什麽樣的好處。當然,也有助於我們理解其他相關的知識。等到未來的某一天,當我們遇到更復雜的情況,用今天的MVVM也不能解決的時候,就可以順著這樣的思考脈絡,重新進行架構設計,散發出自己的光。
備註:虛擬DOM與組件化
不管是虛擬DOM也好,還是組件化也罷,都是一種開發策略,而不是架構模式上考慮的問題。換句話說,它們與MV*是兩個維度上的事情。所以把虛擬DOM和組件化扯入到MVC,MVP,MVVM的差異中並沒有意義。
MVC/MVP/MVVM