不要再問我MVC、MVP、MVVM了

chua1989 發表於 2020-08-01

網路上有很多類似的討論。比如

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

廖雪峰:MVVM

司徒正美: 各自用一句話來概括MVC、MVP、MVVM的差異特點

。。。

但是說的往往比較概念化、空泛,初學者很難理解。本篇用最簡單的例子講解這三者,看完本篇,你就不會再糾結這個問題了

 

框架的起源與目的

1.框架是一個可複用的設計構件

框架就是為大規模複用而生,為大型專案而生。小型專案由於不需要大規模複用,可不需要框架。

表現為元件的複用、專案的移植都應該非常容易。

2.框架規定了一種固定的、結構化的方式進行程式碼的組織。

框架的目標是進行有效的知識積累。為此,相關的技術當以固定的格式,以程式碼、文件、模型等方式固化下來。

表現為:框架規定了程式碼的結構層次(“高內聚、低耦合”),以及各個層次之間的關係;互動以及控制流程。

這塊可能有點抽象,簡單理解:框架就是規定了結構分層,每一層是幹什麼用的。然後你按照框架規定的正規化進行程式設計,框架幫你處理層與層之間的互動與控制。

 

MVC

Model-View-Controller

view層:使用者介面

controller層:業務邏輯、路由

model層:資料結構、資料儲存

不要再問我MVC、MVP、MVVM了

以jsp作為頁面模板開發為例,其他asp/php等類似(為了方便,下面用V表示View,C表示controller, M表示Model。後面的例子同理)

view層:

   jsp頁面模板是屬於這一層。

controller層:

  響應jsp頁面的使用者操作並處理的Servlet。servlet需要從model獲取一些資料結構和資料,以及傳遞資料到model層儲存,所以資料流程是C到M,M也可以到C。

  Servlet處理中路由功能會告訴伺服器處理完成之後下一個展示的該是哪個jsp頁面。這塊僅僅是路由功能,servlet和“下一個展示的jsp頁面”沒有互動和資料的傳遞。所以V到C是單項的。

model層:

  這一層主要定義基本資料結構和資料儲存。jsp頁面模板中,需要從M層獲取最新的資料組裝頁面,所以是M到V。

到此,對MVC框架就應該比較瞭解了。

 

MVC框架有其他變種,都是基於這種模式的擴充。C和M層必然是雙向的,那些認為是單向的模式,本人不敢苟同,也實在想不出單向能夠解決所有問題的場景。

複雜的業務中,C層必然從M層讀取資料處理業務。如果這一條不成立,那麼C層能做的僅僅是路由功能。可以想象,C層將多麼的單薄,M層將多麼的厚重,這必然不是框架的目標,也不是好的框架。

 

MVP

Model-View-Presenter

view層:使用者介面

presenter層:業務邏輯、路由

model層:資料結構、資料儲存

 不要再問我MVC、MVP、MVVM了

為什麼要MVP?從MVC的流程可以看到,V層資料是從M層獲取的。最上層和最底層直接互動,意味著什麼?

在前後端沒有分工的時候沒有問題,V層開發者就是M層開發者,所以對M的資料結構瞭如指掌,要什麼資料知道怎麼去獲取。

但是V層越來越複雜、ajax做區域性頁面渲染的出現以及前後端分工導致V層開發者更專注於互動設計,已經沒有精力去掌控M層的細節了。

這時,V層希望的是:有特定的介面返回約定好的資料。這些資料和M層的資料可能有很大的不同,應該有一箇中間層來提供。之前的MVC的C層來幹這件事比較合適。所以變成了P層,P層除了幹C層的事,還多了為V層提供各種各樣功能介面。

現在V層和M層完全分來了。前後端的開發人員都能將精力集中在該乾的事上。

 

MVVM

Model-View-ViewModel

view層:使用者介面、響應viewModel變化處理

viewModel層:介面業務邏輯、路由

model層:後臺業務邏輯、資料結構、資料儲存

 不要再問我MVC、MVP、MVVM了

MVVM更像是前端程式設計師的自嗨。當然它的出現也是有必要的,前端的複雜度指數級的上升。比如你可以看到類似Scratch這樣純前端的圖形化程式設計系統,程式碼量以千萬行為單位,是有必要為這樣龐大的系統做框架設計的。MVVM就是為此而生。

在MVVM的視界裡,M層不是關鍵,你可以把整個後臺都看成M層。

V層是使用者介面,並且感知到VM層資料的變化V層會跟隨變化(你不需要知道V層怎麼感知到VM層資料變化的,這就是框架幫你做的事)。

VM層才是重點。在框架中,VM層定義了V層需要的直接資料結構(所以才帶Model字樣),V層的事件以及資料變化都會經過框架,流入VM層進行處理,進行業務邏輯的處理、資料的變更以及和M層的互動。

Angular、Vue、React都是類似的。簡單理解:前端開發中模板即V層,後臺屬於M層,按照框架的正規化開發的部分就是VM層。

細心的你可能看到了一點:VM層居然包含了“路由”功能。在MVC、MVP框架中,路由都是屬於伺服器功能,單頁面的興起,讓路由納入了前端的功能圈。聰明的你應該想到,MVVM框架也是為單頁面而生

當然這些MVVM框架都支援在服務端渲染,一旦用在服務端渲染,框架就失去了V層的響應式,直接就程式設計練一個模板引擎了,不能再稱之位MVVM框架了。

 

 

到此,你應該對三種框架有了足夠的認識了。

MVC和MVP都主要為簡化服務端渲染檢視而設計的。MVVM則是為了簡化前端頁面開發而設計的。

上面的示例以Web頁面來描述的。同理推廣到其他檢視互動應用都是可以的。

說一個題外話,框架和庫的區別就比較明顯了。庫只是提供擴充的功能,而框架則是規定了程式碼分層,並讓你必須按它的結構進行程式碼編寫。這就是Jquery不是框架的原因。