深入了解MV**模式
前言:做客戶端開發、前端開發,大致都應該聽說過這么幾個名詞MVC、MVP、MVVM,這些架構的思想大多是為了解決界面應用程序復雜的邏輯問題。同時這些框架的核心目的在于,職責分離,不同的層次要做不同的事情。
無論是哪種MV**系列,都涉及到了Model和View,如果單純的只有Model和View,他們是沒有辦法一起協同工作的,所以就有了各種MV..的設計模式
MVXX模式:
- MVC
- MVP
- MVVM
這三種架構模式都是現在比較流行的,在不同的項目中,可能采用不同的架構模式,今天我們就圍繞著這三種架構模式的試用場景介紹一下他們的概念,以及異同。
MVC
MVC(Model-View-Controller),Model:邏輯模型,View:視圖模型,Controller控制器。簡單說這就是一種設計應用程序的思想,目的在于將業務邏輯、數據、界面分離,將業務邏輯聚集到一個部件里面,在改進或者想要定制界面及用戶交互時,不需要重寫編寫業務邏輯。Controller和View都依賴Model層,Controller和View相互依賴。
操作的過程:用戶在界面上進行操作(例如手機屏幕),這個時候View會捕捉到用戶的操作,然后將這個操作的處理權利交給Controller,Controller會對來自View的數據進行預處理,決定調用哪個Model的接口,然后由Model執行相應的邏輯,當Model變更之后,再利用觀察者模式通知View,View通過觀察者模式收到Model的消息之后,向Model請求最新的數據,然后更新頁面,如下圖:
看似沒有什么特別的地方,但是由幾個需要特別關注的關鍵點:
- View是把控制權交移給Controller,Controller執行應用程序相關的應用邏輯(對來自View數據進行預處理、決定調用哪個Model的接口等等)。
- Controller操作Model,Model執行業務邏輯對數據進行處理。但不會直接操作View,可以說它是對View無知的。
- View和Model的同步消息是通過觀察者模式進行,而同步操作是由View自己請求Model的數據然后對視圖進行更新。
需要特別注意的是MVC模式的精髓在于第三點:Model的更新是通過觀察者模式告知View的,具體表現形式可以是Pub/Sub或者是觸發Events。而網上很多對于MVC的描述都沒有強調這一點。通過觀察者模式的好處就是:不同的MVC三角關系可能會有共同的Model,一個MVC三角中的Controller操作了Model以后,兩個MVC三角的View都會接受到通知,然后更新自己。保持了依賴同一塊Model的不同View顯示數據的實時性和準確性。我們每天都在用的觀察者模式,在幾十年前就已經被大神們整合到MVC的架構當中。
優點
- 首先最重要的一點是多個視圖能共享一個模型,同一個模型可以被不同的視圖重用,大大提高了代碼的可重用性。
- 由于MVC的三個模塊相互獨立,在其中改變一個,其他兩個可以保持不變,這樣可以把耦合降得很低,這樣可以使開發人員可以只關注整個系統中的某一層
- 控制器提高了應用程序的靈活性和可配置型。控制器可以用來連接不同的模型和視圖去完成用戶的需求,這樣控制器可以為構造應用程序提供強有力的手段
缺點
- 增加了系統結構的實現的復雜性
- 視圖與控制器之間的聯系過于緊密,視圖如果沒有控制器的存在,能夠做的事情少之又少,這樣視圖就很難獨立應用了
- 視圖對模型的數據的訪問效率過低,因為之間需要多次的調用
- View無法組件化,View依賴于特定的Model,如果需要把這個View抽出來用在下一個應用程序復用就比較困難了
MVP
Model(Model View Presenter),Model:邏輯模型,View:視圖模型,Presenter:接口。
關于MVP的定義:
- MVC的演化版本,讓Model和View完全解耦
- 代碼清晰,不過增加了很多類
MVP中的P,是Presenter的含義,和MVC比較類似,都是將用戶對View的操作交付給Presenter,Presenter會執行相應的邏輯,在這過程中會操作Model,當Model執行完業務邏輯之后,同樣是通過觀察者模式把自己的結果傳遞出去,不過不是告訴View,而是告訴Presenter,Presenter得到消息后,通過View的接口更新頁面。
在Android中,我們的View可能僅僅就是個布局文件,它能做的事情少之又少,真正與布局文件進行數據綁定操作的事Activity,所以這樣做就使Activity即像View又像Controller。
應用了MVP之后:
- View:對應Activity,負責View的繪制以及與用戶交互
- Model:業務邏輯和實體模型
- Presenter:負責完成View與Model之間的交互
應用兩張圖來說明上述內容:
MVP的優點
- 便于測試。Presenter對View是通過接口進行,在對Presenter進行不依賴UI環境的單元測試的時候。可以通過Mock一個View對象,這個對象只需要實現了View的接口即可。然后依賴注入到Presenter中,單元測試的時候就可以完整的測試Presenter應用邏輯的正確性。這里根據上面的例子給出了Presenter的單元測試樣例。
- View可以進行組件化。在MVP當中,View不依賴Model。這樣就可以讓View從特定的業務場景中脫離出來,可以說View可以做到對業務完全無知。它只需要提供一系列接口提供給上層操作。這樣就可以做到高度可復用的View組件。
MVP的缺點
- 代碼量會一些,實現的難度也會增加一些
MVP與MVC區別
如下圖所示:
MVVM
MVVM是Model-View-ViewModel的簡寫,MVVM是思想上的一種變革,也可以看成是MVP的一種變革,它是將"數據模型數據雙向綁定"的思想作為核心,因此在View和Model之間便不需要我們寫聯系了,我們在修改數據的時候視圖就可以發生變化,我們在修改視圖的時候數據也是會發生變化的,可以在一定程度上提高我們的開發效率的。
調用關系
MVVM的調用關系和MVP一樣。但是,在ViewModel當中會有一個叫Binder,或者是Data-binding engine的東西。以前全部由Presenter負責的View和Model之間數據同步操作交由給Binder處理。你只需要在View的模版語法當中,指令式地聲明View上的顯示的內容是和Model的哪一塊數據綁定的。當ViewModel對進行Model更新的時候,Binder會自動把數據更新到View上去,當用戶對View進行操作(例如表單輸入),Binder也會自動把數據更新到Model上去。這種方式稱為:Two-way data-binding,雙向數據綁定。可以簡單而不恰當地理解為一個模版引擎,但是會根據數據變更實時渲染。
也就是說,MVVM把View和Model的同步邏輯自動化了。以前Presenter負責的View和Model同步不再手動地進行操作,而是交由框架所提供的Binder進行負責。只需要告訴Binder,View顯示的數據對應的是Model哪一部分即可。
Android官方推出的MVVM的DataBinding,便是一個雙向綁定的庫。
優點
- 提高可維護性。解決了MVP大量的手動View和Model同步的問題,提供雙向綁定機制。提高了代碼的可維護性。
- 簡化測試。因為同步邏輯是交由Binder做的,View跟著Model同時變更,所以只需要保證Model的正確性,View就正確。大大減少了對View同步更新的測試。
缺點
- 過于簡單的圖形界面不適用,或說牛刀殺雞。
- 對于大型的圖形應用程序,視圖狀態較多,ViewModel的構建和維護的成本都會比較高。
- 數據綁定的聲明是指令式地寫在View的模版當中的,這些內容是沒辦法去打斷點debug的。