關於MV*模式的一己之見,科普向

jiangqizheng發表於2019-01-28

一直對mv*模式不太瞭解,終於趁著週末閒暇之餘試著去理解了以下,以下是個人總結,歡迎討論,如有錯誤請指教。

傳統mvc

mvc是一套設計模式的組合,最初是用於解決客戶端圖形介面應用程式的模組化問題。

由於使用者介面邏輯的更改往往要比業務邏輯更頻繁,並且在某些情況下,應用程式需要以不同的方式來顯示同一資料等…諸多問題下,解決方案mvc就此誕生。

Model-View-Controller (MVC) 將程式劃分為三層

  • 模型 model封裝了程式指定的資料和邏輯(資料與業務)

  • 檢視 view是對資料的顯示(介面)

  • 控制器 controller能夠響應使用者操作來通知model進行更新(只是通知,真實處理是由model自身執行)或者view的更新(事件)

model不只是資料的整合,還包含了對資料進行處理的能力。

三者依賴和呼叫關係可以參考下圖,主要是懶得畫。

關於MV*模式的一己之見,科普向
關於MV*模式的一己之見,科普向

依賴:可以很明確的看到view和controller都依賴於model。

呼叫:

1. view接收到輸入,轉發給controller
2. controller 對輸入進行預處理後,呼叫匹配的model介面
3. model執行業務邏輯,變更資料後通過觀察者/訂閱模式通知所有已註冊的觀察者(view)
4. view收到model變更通知,請求更新後的資料,更新介面
複製程式碼

關於呼叫關係可以看出,mvc主要由觀察者模式構築,策略模式(controller可以算作view的策略之一)以及其他模式作為輔助

依賴關係可以在呼叫流程中得到驗證,view由於是直接向model請求資料並更新的,所以view實質上是知道model內資料的相關結構的,controller同理。這就導致了view與controller無法脫離model,並且不可在其他程式內部複用。

被動mvc

時代的發展,導致現在web應用的大行其道。

與客戶端圖形介面程式不同,web應用主要是通過http協議進行通訊,但http協議是單工協議並且是無狀態的,伺服器無法直接給客戶端推送資料,這也就導致了view訂閱model更新的模式被打破。

變更後web應用mvc模式大致流程為:

1. 客戶端傳送請求
2. 服務端通過路由呼叫相應的controller ,對來自客戶端得請求進行格式化預處理然後呼叫相應的 model 介面
3. model執行業務邏輯,使用資料渲染模版檢視,伺服器回覆請求
5. 客戶端更新
複製程式碼

演化

mvp

由於mvc模式下的view與model的高度耦合,view無法被元件化,複用程度低,所以mvp被提出

關於MV*模式的一己之見,科普向

mvp直接切斷了view和model的繫結關係,解除了二者的耦合。

controller 被替換(重新命名)成了 presenter

mvp呼叫改變為:

1. view接收到輸入,轉發給presenter
2. presenter對輸入進行預處理後,呼叫匹配的model介面
3. model執行業務邏輯,變更資料後通過觀察者模式通知presenter
4. presenter獲取更新後的資料,通過view提供的更新介面更新進行介面更新
複製程式碼

實質上mvp就是mvc的另一形式,presenter相比controller包含了更多的邏輯變得厚重(接受model的變更通知,與更新view的能力)。而view不再依賴model,對於model以及presenter內的資料與業務完全無感知,所以view可以被抽象用於不同的應用中,只要提供對應的介面。

mvvm

mvvm是mvp的改良版,相對於mvp而言,在依賴關係上與呼叫關係上都沒有什麼變化,所以就不放圖了:)

mvp相比mvc來說,它抽離了view提高了模組化程度,但presenter層既承擔了對view事件的預處理,又需要提供對於view的資料同步,導致了邏輯過於繁瑣厚重,難以開發與維護。

於是Model-View-ViewModel被提出,vm承載了presenter的功能,並且將model與view之間的資料更新抽離出來,提供了自動化的能力,開發人員不必再手動維護model與view之間的更新邏輯,可以更專注於核心業務的開發。

mvc => mvp => mvvm 模式的更新,本質上是由於專案複雜度不斷增加,新的需求被不斷被提出,為了維持現狀而被迫的升級改良。

新模式這方面,新模式是不可能有新模式的,這輩子不可能有新模式的。換模式又不會搞,就是改良模式這種東西,才能維持的了生活這樣子。

前端

終於到前端了,作為本職工作,前端戰五渣,雖然不懂,但還是要勉強一寫,關於模式的理論在上文中已經大致介紹了一遍,下面只是一些關於模式與前端框架的雜談。

前端框架與庫千千萬,模式卻不多,也就mvc與mvvm佔主流。

Angular與Vue可以算是主流的mvvm框架/庫,由於Angular只是淺顯的走過一次教程所以就不提了。

Vue

關於Vue,在我看來,框架自身可以算是一層vm,至於我們寫的模版,自然是view。但有很多人認為model應該是data也就是資料。但我認為,開發人員所寫的js大多都屬於model。

Vue的實現可以分為兩步,對資料的劫持與解析dom後的資料監聽(訂閱者),實現了一套data=>view,view=>data的關係,用於自動化處理資料,開發者無需關注dom的更新,只需要為對應的事件來編寫匹配的,用於更新data的函式即可(包含了ajax對於後端的請求)。

前後端分離的模式下,後端基本上只需要提供RESTful API即可。

React

React 起源於 Facebook 的內部專案,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。

React應該是一個屬於mvc的檢視庫,功能非常簡單而純粹,根據state渲染view。

關於react沒有多寫,第一是感覺言盡於此,描述的挺清楚的。其次是因為寫這篇總結純屬意外,本來前兩天在看一些flux實現與redux原始碼(才四五百行,註釋都還寫的挺清楚,對react有興趣的朋友可以看看)然後莫名其妙就開始看mvc相關內容,跑偏了,後面就放棄治療了。

如果有機會的話,下一篇估計會寫關於flux=>redux的文章,react留到下一篇再聊。


參考資料如下。

微軟msdn:MVC模式

阮一峰:談談MVC模式

阮一峰:MVC,MVP 和 MVVM 的圖示

百度文庫:深入淺出設計模式之MVC

介面之下:還原真實的MV*模式

相關文章