成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

切圖崽的自我修養(yǎng)-[MVVM] Js MV*模式淺談

bluesky / 3190人閱讀

摘要:在沒有環(huán)境下對進(jìn)行單元測試的時候,應(yīng)用邏輯正確性是無法驗(yàn)證的更新的時候,無法對的更新操作進(jìn)行斷言。對是通過接口進(jìn)行,在對進(jìn)行不依賴環(huán)境的單元測試的時候。這里根據(jù)上面的例子給出了的單元測試樣例。年微軟工程師在自己的博客上首次公布了模式。

前言

做客戶端開發(fā)、前端開發(fā)對MVC、MVP、MVVM這些名詞不了解也應(yīng)該大致聽過,都是為了解決圖形界面應(yīng)用程序復(fù)雜性管理問題而產(chǎn)生的應(yīng)用架構(gòu)模式。網(wǎng)上很多文章關(guān)于這方面的討論比較雜亂,各種MV模式之間的區(qū)別分不清,甚至有些描述都是錯誤的。本文追根溯源,從最經(jīng)典的Smalltalk-80 MVC模式開始逐步還原圖形界面之下最真實(shí)的MV模式。

GUI程序所面臨的問題

圖形界面的應(yīng)用程序提供給用戶可視化的操作界面,這個界面提供給數(shù)據(jù)和信息。用戶輸入行為(鍵盤,鼠標(biāo)等)會執(zhí)行一些應(yīng)用邏輯,應(yīng)用邏輯(application logic)可能會觸發(fā)一定的業(yè)務(wù)邏輯(business logic)對應(yīng)用程序數(shù)據(jù)的變更,數(shù)據(jù)的變更自然需要用戶界面的同步變更以提供最準(zhǔn)確的信息。例如用戶對一個電子表格重新排序的操作,應(yīng)用程序需要響應(yīng)用戶操作,對數(shù)據(jù)進(jìn)行排序,然后需要同步到界面上。

在開發(fā)應(yīng)用程序的時候,以求更好的管理應(yīng)用程序的復(fù)雜性,基于職責(zé)分離(Speration of Duties)的思想都會對應(yīng)用程序進(jìn)行分層。在開發(fā)圖形界面應(yīng)用程序的時候,會把管理用戶界面的層次稱為View,應(yīng)用程序的數(shù)據(jù)為Model(注意這里的Model指的是Domain Model,這個應(yīng)用程序?qū)π枰鉀Q的問題的數(shù)據(jù)抽象,不包含應(yīng)用的狀態(tài),可以簡單理解為對象)。Model提供數(shù)據(jù)操作的接口,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。

有了View和Model的分層,那么問題就來了:View如何同步Model的變更,View和Model之間如何粘合在一起。

帶著這個問題開始探索MV模式,會發(fā)現(xiàn)這些模式之間的差異可以歸納為對這個問題處理的方式的不同。而幾乎所有的MV模式都是經(jīng)典的Smalltalk-80 MVC的修改版。

Smalltalk-80 MVC 歷史背景

早在上個世紀(jì)70年代,美國的施樂公司(Xerox)的工程師研發(fā)了Smalltalk編程語言,并且開始用它編寫圖形界面的應(yīng)用程序。而在Smalltalk-80這個版本的時候,一位叫Trygve Reenskaug的工程師設(shè)計了MVC圖形應(yīng)用程序的架構(gòu)模式,極大地降低了圖形應(yīng)用程序的管理難度。而在四人幫(GoF)的設(shè)計模式當(dāng)中并沒有把MVC當(dāng)做是設(shè)計模式,而僅僅是把它看成解決問題的一些類的集合。Smalltalk-80 MVC和GoF描述的MVC是最經(jīng)典的MVC模式。

MVC的依賴關(guān)系

MVC出了把應(yīng)用程序分成View、Model層,還額外的加了一個Controller層,它的職責(zé)為進(jìn)行Model和View之間的協(xié)作(路由、輸入預(yù)處理等)的應(yīng)用邏輯(application logic);Model進(jìn)行處理業(yè)務(wù)邏輯。Model、View、Controller三個層次的依賴關(guān)系如下:

Controller和View都依賴Model層,Controller和View可以互相依賴。在一些網(wǎng)上的資料Controller和View之間的依賴關(guān)系可能不一樣,有些是單向依賴,有些是雙向依賴,這個其實(shí)關(guān)系不大,后面會看到它們的依賴關(guān)系都是為了把處理用戶行為觸發(fā)的事件處理權(quán)交給Controller。

MVC的調(diào)用關(guān)系

用戶的對View操作以后,View捕獲到這個操作,會把處理的權(quán)利交移給Controller(Pass calls);Controller會對來自View數(shù)據(jù)進(jìn)行預(yù)處理、決定調(diào)用哪個Model的接口;然后由Model執(zhí)行相關(guān)的業(yè)務(wù)邏輯;當(dāng)Model變更了以后,會通過觀察者模式(Observer Pattern)通知View;View通過觀察者模式收到Model變更的消息以后,會向Model請求最新的數(shù)據(jù),然后重新更新界面。如下圖:

看似沒有什么特別的地方,但是由幾個需要特別關(guān)注的關(guān)鍵點(diǎn):

View是把控制權(quán)交移給Controller,Controller執(zhí)行應(yīng)用程序相關(guān)的應(yīng)用邏輯(對來自View數(shù)據(jù)進(jìn)行預(yù)處理、決定調(diào)用哪個Model的接口等等)。

Controller操作Model,Model執(zhí)行業(yè)務(wù)邏輯對數(shù)據(jù)進(jìn)行處理。但不會直接操作View,可以說它是對View無知的。

View和Model的同步消息是通過觀察者模式進(jìn)行,而同步操作是由View自己請求Model的數(shù)據(jù)然后對視圖進(jìn)行更新。

需要特別注意的是MVC模式的精髓在于第三點(diǎn):Model的更新是通過觀察者模式告知View的,具體表現(xiàn)形式可以是Pub/Sub或者是觸發(fā)Events。而網(wǎng)上很多對于MVC的描述都沒有強(qiáng)調(diào)這一點(diǎn)。通過觀察者模式的好處就是:不同的MVC三角關(guān)系可能會有共同的Model,一個MVC三角中的Controller操作了Model以后,兩個MVC三角的View都會接受到通知,然后更新自己。保持了依賴同一塊Model的不同View顯示數(shù)據(jù)的實(shí)時性和準(zhǔn)確性。我們每天都在用的觀察者模式,在幾十年前就已經(jīng)被大神們整合到MVC的架構(gòu)當(dāng)中。

這里有一個MVC模式的JavaScript Demo,實(shí)現(xiàn)了一個小的TodoList應(yīng)用程序。經(jīng)典的Smalltalk-80 MVC不需要任何框架支持就可以實(shí)現(xiàn)。目前Web前端框架當(dāng)中只有一個號稱是嚴(yán)格遵循Smalltalk-80 MVC模式的:maria.js。

MVC的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

把業(yè)務(wù)邏輯和展示邏輯分離,模塊化程度高。且當(dāng)應(yīng)用邏輯需要變更的時候,不需要變更業(yè)務(wù)邏輯和展示邏輯,只需要Controller換成另外一個Controller就行了(Swappable Controller)。

觀察者模式可以做到多視圖同時更新。

缺點(diǎn):

1.Controller測試?yán)щy。因?yàn)橐晥D同步操作是由View自己執(zhí)行,而View只能在有UI的環(huán)境下運(yùn)行。在沒有UI環(huán)境下對Controller進(jìn)行單元測試的時候,應(yīng)用邏輯正確性是無法驗(yàn)證的:Model更新的時候,無法對View的更新操作進(jìn)行斷言。
2.View無法組件化。View是強(qiáng)依賴特定的Model的,如果需要把這個View抽出來作為一個另外一個應(yīng)用程序可復(fù)用的組件就困難了。因?yàn)椴煌绦虻牡腄omain Model是不一樣的

MVC Model 2

在Web服務(wù)端開發(fā)的時候也會接觸到MVC模式,而這種MVC模式不能嚴(yán)格稱為MVC模式。經(jīng)典的MVC模式只是解決客戶端圖形界面應(yīng)用程序的問題,而對服務(wù)端無效。服務(wù)端的MVC模式又自己特定的名字:MVC Model 2,或者叫JSP Model 2,或者直接就是Model 2 。Model 2客戶端服務(wù)端的交互模式如下:

服務(wù)端接收到來自客戶端的請求,服務(wù)端通過路由規(guī)則把這個請求交由給特定的Controller進(jìn)行處理,Controller執(zhí)行相應(yīng)的應(yīng)用邏輯,對Model進(jìn)行操作,Model執(zhí)行業(yè)務(wù)邏輯以后;然后用數(shù)據(jù)去渲染特定的模版,返回給客戶端。

因?yàn)镠TTP協(xié)議是單工協(xié)議并且是無狀態(tài)的,服務(wù)器無法直接給客戶端推送數(shù)據(jù)。除非客戶端再次發(fā)起請求,否則服務(wù)器端的Model的變更就無法告知客戶端。所以可以看到經(jīng)典的Smalltalk-80 MVC中Model通過觀察者模式告知View更新這一環(huán)被無情地打破,不能稱為嚴(yán)格的MVC。

Model 2模式最早在1998年應(yīng)用在JSP應(yīng)用程序當(dāng)中,JSP Model 1應(yīng)用管理的混亂誘發(fā)了JSP參考了客戶端MVC模式,催生了Model 2。

后來這種模式幾乎被應(yīng)用在所有語言的Web開發(fā)框架當(dāng)中。PHP的ThinkPHP,Python的Dijango、Flask,NodeJS的Express,Ruby的RoR,基本都采納了這種模式。平常所講的MVC基本是這種服務(wù)端的MVC。

MVP

MVP模式有兩種:

Passive View

Supervising Controller

而大多數(shù)情況下討論的都是Passive View模式。本文會對PV模式進(jìn)行較為詳細(xì)的介紹,而SC模式則簡單提及。

歷史背景

MVP模式是MVC模式的改良。在上個世紀(jì)90年代,IBM旗下的子公司Taligent在用C/C++開發(fā)一個叫CommonPoint的圖形界面應(yīng)用系統(tǒng)的時候提出來的。

MVP(Passive View)的依賴關(guān)系

MVP模式把MVC模式中的Controller換成了Presenter。MVP層次之間的依賴關(guān)系如下:

MVP打破了View原來對于Model的依賴,其余的依賴關(guān)系和MVC模式一致。

MVP(Passive View)的調(diào)用關(guān)系

既然View對Model的依賴被打破了,那View如何同步Model的變更?看看MVP的調(diào)用關(guān)系:

和MVC模式一樣,用戶對View的操作都會從View交移給Presenter。Presenter會執(zhí)行相應(yīng)的應(yīng)用程序邏輯,并且對Model進(jìn)行相應(yīng)的操作;而這時候Model執(zhí)行完業(yè)務(wù)邏輯以后,也是通過觀察者模式把自己變更的消息傳遞出去,但是是傳給Presenter而不是View。Presenter獲取到Model變更的消息以后,通過View提供的接口更新界面。

關(guān)鍵點(diǎn):

View不再負(fù)責(zé)同步的邏輯,而是由Presenter負(fù)責(zé)。Presenter中既有應(yīng)用程序邏輯也有同步邏輯。

View需要提供操作界面的接口給Presenter進(jìn)行調(diào)用。(關(guān)鍵)
對比在MVC中,Controller是不能操作View的,View也沒有提供相應(yīng)的接口;

而在MVP當(dāng)中,Presenter可以操作View,View需要提供一組對界面操作的接口給Presenter進(jìn)行調(diào)用;Model仍然通過事件廣播自己的變更,但由Presenter監(jiān)聽而不是View。

MVP(Passive View)的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

便于測試。Presenter對View是通過接口進(jìn)行,在對Presenter進(jìn)行不依賴UI環(huán)境的單元測試的時候。可以通過Mock一個View對象,這個對象只需要實(shí)現(xiàn)了View的接口即可。然后依賴注入到Presenter中,單元測試的時候就可以完整的測試Presenter應(yīng)用邏輯的正確性。這里根據(jù)上面的例子給出了Presenter的單元測試樣例。

View可以進(jìn)行組件化。在MVP當(dāng)中,View不依賴Model。這樣就可以讓View從特定的業(yè)務(wù)場景中脫離出來,可以說View可以做到對業(yè)務(wù)完全無知。它只需要提供一系列接口提供給上層操作。這樣就可以做到高度可復(fù)用的View組件。

缺點(diǎn):

Presenter中除了應(yīng)用邏輯以外,還有大量的View->Model,Model->View的手動同步邏輯,造成Presenter比較笨重,維護(hù)起來會比較困難。

MVP(Supervising Controller)

上面講的是MVP的Passive View模式,該模式下View非常Passive,它幾乎什么都不知道,Presenter讓它干什么它就干什么。而Supervising Controller模式中,Presenter會把一部分簡單的同步邏輯交給View自己去做,Presenter只負(fù)責(zé)比較復(fù)雜的、高層次的UI操作,所以可以把它看成一個Supervising Controller。

Supervising Controller模式下的依賴和調(diào)用關(guān)系:

因?yàn)镾upervising Controller用得比較少,對它的討論就到這里為止

MVVM 歷史背景

MVVM模式最早是微軟公司提出,并且了大量使用在.NET的WPF和Sliverlight中。2005年微軟工程師John Gossman在自己的博客上首次公布了MVVM模式。

ViewModel

MVVM代表的是Model-View-ViewModel,這里需要解釋一下什么是ViewModel。ViewModel的含義就是 "Model of View",視圖的模型。它的含義包含了領(lǐng)域模型(Domain Model)和視圖的狀態(tài)(State)。 在圖形界面應(yīng)用程序當(dāng)中,界面所提供的信息可能不僅僅包含應(yīng)用程序的領(lǐng)域模型。還可能包含一些領(lǐng)域模型不包含的視圖狀態(tài),例如電子表格程序上需要顯示當(dāng)前排序的狀態(tài)是順序的還是逆序的,而這是Domain Model所不包含的,但也是需要顯示的信息。

可以簡單把ViewModel理解為頁面上所顯示內(nèi)容的數(shù)據(jù)抽象,和Domain Model不一樣,ViewModel更適合用來描述View。

MVVM的依賴

MVVM的依賴關(guān)系和MVP依賴,只不過是把P換成了VM。

MVVM的調(diào)用關(guān)系

MVVM的調(diào)用關(guān)系和MVP一樣。但是,在ViewModel當(dāng)中會有一個叫Binder,或者是Data-binding engine的東西。以前全部由Presenter負(fù)責(zé)的View和Model之間數(shù)據(jù)同步操作交由給Binder處理。你只需要在View的模版語法當(dāng)中,指令式地聲明View上的顯示的內(nèi)容是和Model的哪一塊數(shù)據(jù)綁定的。當(dāng)ViewModel對進(jìn)行Model更新的時候,Binder會自動把數(shù)據(jù)更新到View上去,當(dāng)用戶對View進(jìn)行操作(例如表單輸入),Binder也會自動把數(shù)據(jù)更新到Model上去。這種方式稱為:Two-way data-binding,雙向數(shù)據(jù)綁定??梢院唵味磺‘?dāng)?shù)乩斫鉃橐粋€模版引擎,但是會根據(jù)數(shù)據(jù)變更實(shí)時渲染。

也就是說,MVVM把View和Model的同步邏輯自動化了。以前Presenter負(fù)責(zé)的View和Model同步不再手動地進(jìn)行操作,而是交由框架所提供的Binder進(jìn)行負(fù)責(zé)。只需要告訴Binder,View顯示的數(shù)據(jù)對應(yīng)的是Model哪一部分即可。

MVVM的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

提高可維護(hù)性。解決了MVP大量的手動View和Model同步的問題,提供雙向綁定機(jī)制。提高了代碼的可維護(hù)性。

簡化測試。因?yàn)橥竭壿嬍墙挥葿inder做的,View跟著Model同時變更,所以只需要保證Model的正確性,View就正確。大大減少了對View同步更新的測試。

缺點(diǎn):

過于簡單的圖形界面不適用,或說牛刀殺雞。

對于大型的圖形應(yīng)用程序,視圖狀態(tài)較多,ViewModel的構(gòu)建和維護(hù)的成本都會比較高。

數(shù)據(jù)綁定的聲明是指令式地寫在View的模版當(dāng)中的,這些內(nèi)容是沒辦法去打斷點(diǎn)debug的。

結(jié)語

可以看到,從MVC->MVP->MVVM,就像一個打怪升級的過程。后者解決了前者遺留的問題,把前者的缺點(diǎn)優(yōu)化成了優(yōu)點(diǎn)。同樣的Demo功能,代碼從最開始的一堆文件,優(yōu)化成了最后只需要20幾行代碼就完成。MV*模式之間的區(qū)分還是蠻清晰的,希望可以給對這些模式理解比較模糊的同學(xué)帶來一些參考和思路。

本文轉(zhuǎn)載自界面之下:還原真實(shí)的MV*模式

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80618.html

相關(guān)文章

  • 切圖崽的自我修養(yǎng)-[MVVM] Js MV*模式淺談

    摘要:在沒有環(huán)境下對進(jìn)行單元測試的時候,應(yīng)用邏輯正確性是無法驗(yàn)證的更新的時候,無法對的更新操作進(jìn)行斷言。對是通過接口進(jìn)行,在對進(jìn)行不依賴環(huán)境的單元測試的時候。這里根據(jù)上面的例子給出了的單元測試樣例。年微軟工程師在自己的博客上首次公布了模式。 前言 做客戶端開發(fā)、前端開發(fā)對MVC、MVP、MVVM這些名詞不了解也應(yīng)該大致聽過,都是為了解決圖形界面應(yīng)用程序復(fù)雜性管理問題而產(chǎn)生的應(yīng)用架構(gòu)模式。網(wǎng)上...

    shleyZ 評論0 收藏0
  • 切圖崽的自我修養(yǎng)-[MVVM] 如何監(jiān)聽數(shù)據(jù)變化

    摘要:數(shù)據(jù)監(jiān)聽模式的核心就是數(shù)據(jù)變化驅(qū)動視圖更新,其中關(guān)鍵的一點(diǎn)就是,我們?nèi)绾文苤罃?shù)據(jù)發(fā)生了變化發(fā)布訂閱模型通過事件的發(fā)布監(jiān)聽的模式來實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽即數(shù)據(jù)變化后,發(fā)布者會觸發(fā)自定義的某個事件比如,然后訂閱者捕獲到這個事件后,實(shí)現(xiàn)后續(xù)處理值判斷視圖 數(shù)據(jù)監(jiān)聽 vm模式的核心就是數(shù)據(jù)變化驅(qū)動視圖更新,其中關(guān)鍵的一點(diǎn)就是,我們?nèi)绾文苤罃?shù)據(jù)發(fā)生了變化? 發(fā)布-訂閱模型 通過事件的發(fā)布/監(jiān)聽的模式來...

    malakashi 評論0 收藏0
  • 切圖崽的自我修養(yǎng)-[MVVM] 如何監(jiān)聽數(shù)據(jù)變化

    摘要:數(shù)據(jù)監(jiān)聽模式的核心就是數(shù)據(jù)變化驅(qū)動視圖更新,其中關(guān)鍵的一點(diǎn)就是,我們?nèi)绾文苤罃?shù)據(jù)發(fā)生了變化發(fā)布訂閱模型通過事件的發(fā)布監(jiān)聽的模式來實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽即數(shù)據(jù)變化后,發(fā)布者會觸發(fā)自定義的某個事件比如,然后訂閱者捕獲到這個事件后,實(shí)現(xiàn)后續(xù)處理值判斷視圖 數(shù)據(jù)監(jiān)聽 vm模式的核心就是數(shù)據(jù)變化驅(qū)動視圖更新,其中關(guān)鍵的一點(diǎn)就是,我們?nèi)绾文苤罃?shù)據(jù)發(fā)生了變化? 發(fā)布-訂閱模型 通過事件的發(fā)布/監(jiān)聽的模式來...

    lifefriend_007 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<