摘要:由于控件與業(yè)務邏輯之間的緊耦合,相應帶來的問題就是變更的代價增大,以及難以編寫針對性的單元測試。這些東西的組合提供了到譯者注視圖模型后面統(tǒng)一簡稱之間的連接方式。的單元測試可以完全模擬在上用的那些功能。
原文:https://github.com/kuitos/kui...
全部文章:https://github.com/kuitos/kui...
原文:The MVVM Pattern
MVVM 模式跟 Silverlight 這類 XAML 應用平臺是天生合拍的。這是因為 MVVM 模式利用了Silverlight 的一些特殊能力,比如說 數(shù)據(jù)綁定,命令,行為等。MVVM 跟其他一些將表現(xiàn)及UI布局 與展示層邏輯的職責進行分離的模式很相似;如果你對 MVC 模式熟悉的話,你會發(fā)現(xiàn)它與 MVVM 之間存在很多相似的概念。
MVVM 模式的設(shè)計動機譯者注:XAML(Extensible Application Markup Language)是微軟為構(gòu)建GUI程序而創(chuàng)建的一種標記語言,你可以將它等同于 web 體系中 HTML。以下譯文中,web 開發(fā)者可以將 XAML 統(tǒng)一代入為 HTML。Silverlight 則是微軟開發(fā)的一個 富互聯(lián)網(wǎng)應用(Rich Internet Application) 開發(fā)平臺。
諸如 Windows Forms,WPF,Silverlight 以及 Windows Phone 這類開發(fā)技術(shù)都提供了一個默認的體驗,那就是它可以讓開發(fā)者從工具箱中拖拽控件到設(shè)計面板,然后在代碼文件中編寫一定格式的代碼就能完成整個開發(fā)。但是隨著這類應用的增長規(guī)模及作用范圍的變化,復雜的維護性問題就會隨之而來。由于 UI控件 與 業(yè)務邏輯 之間的緊耦合,相應帶來的問題就是 UI 變更的代價增大,以及難以編寫針對性的單元測試。
使用 MVVM 模式來實現(xiàn)應用的主要動機有以下幾點:
它提供了一系列分離的概念。緊耦合,難變化,脆弱的代碼導致了各種各樣的長期維護的問題,最后導致了客戶對交付的軟件較低的滿意度。在應用邏輯及 UI 之間進行干凈的分離將會讓應用更容易測試,維護以及拓展。它提高了代碼的重用性同時使得 開發(fā)-設(shè)計 的工作流變?yōu)榭赡堋?/p>
它與 XAML 平臺是天生合拍的。MVVM 模式的關(guān)鍵推動力來自于 Silverlight 平臺豐富的數(shù)據(jù)綁定技術(shù)棧及一些依賴屬性。這些東西的組合提供了 UI 到 VM(譯者注:view model 視圖模型后面統(tǒng)一簡稱 VM) 之間的連接方式。
它使得 開發(fā)-設(shè)計 的工作流成為可能。當 UI XAML 不是與代碼緊耦合時,設(shè)計師們就很容易去自由的發(fā)揮他們的創(chuàng)造力,從而做出一個更優(yōu)秀的產(chǎn)品。(譯者:簡單來說就是 視圖層 跟 M/VM 層的開發(fā)可以是正交的。)
它增強了應用的可測試性。將 UI 邏輯轉(zhuǎn)移到一個可以獨立實例化的類中,可以讓單元測試的編寫更加容易。(譯者:這一點其實非常重要)
MVVM 模式Model-View-ViewModel 的模式可以用到所有的 XAML 平臺上。它的意圖是在 UI 控件和它們的邏輯之間進行一個純凈的概念分離。
MVVM 模式中有三個核心的組件:model(模型),view(視圖) 以及 view-model(視圖模型)(譯者注:為保證交流中術(shù)語的一致性,model、view、view-model后面均不作翻譯),它們彼此間扮演一個截然不同的角色。下面的插圖展示了這三個組件之間的關(guān)系:
每個組件之間都是相互解耦的,這也使得:
組件可以被交換
內(nèi)部實現(xiàn)可以在不影響其他組件的情況下修改
組件可以獨立的運作
隔離的單元測試
除了理解這三個組件的職責,理解組件之間是如何交互的也同樣重要。在最高的層級上,view 能感知到 view-model,view-model 能感知到 model,但是 model 并不會察覺到 view-model 的存在,同樣的,view-model 也察覺不到 view。
view-model 將 model 類 與 view 隔離開來,這也使得 model 可以獨立于 view 進行演化。
Viewview 的職責是用來定義 結(jié)構(gòu)、布局,及用戶在屏幕上看到的外觀表現(xiàn)。理想情況下,view 僅通過 XAML 定義,以及一些有限的不包含業(yè)務邏輯的代碼。
在一個 Windows Phone 應用中,view 通常是一個頁面。除此之外,一個 view 也可以是一個父 view 的子組件,或者一個 ItemsControl 中的 DataTemplate對象。
一個 view 可以有自己的 view-model,或者繼承自父級 view 的 view-model。視圖通過綁定,或者調(diào)用 view-model 上的方法來獲取數(shù)據(jù)。在運行期間,UI 控件將會響應 view-model 屬性觸發(fā)的變化通知,從而改變 view。
有一些 view 上的交互會觸發(fā) view-model 上的代碼執(zhí)行,比如說按鈕點擊或者選項選中事件。如果這個控件是一個命令源,這個控件的 Command 屬性可以在 view-model 上綁定成一個 ICommand 屬性。當這個控件的命令被調(diào)用,view-model 上相應的代碼就會被執(zhí)行。除了命令,行為也能被附加到 view 的一個對象中,然后監(jiān)聽命令調(diào)用及事件觸發(fā)。作為回應,這個行為之后可以調(diào)用 view-mode 上的 ICommand 或者方法。(譯者:web 領(lǐng)域里這些就是指的模板上的事件綁定語法,通常由框架提供)
Modelmodel 在 MVVM 中是應用的域模型(domain model)實現(xiàn),它包含數(shù)據(jù)模型以及相應的業(yè)務和校驗邏輯。model 對象的例子包括,數(shù)據(jù)倉庫(repositories),業(yè)務對象,數(shù)據(jù)轉(zhuǎn)換對象(DTOs),POCO對象,以及生成的實體及代理對象。
View Model譯者:一個 model 應該包含基本的模型數(shù)據(jù)、基本的業(yè)務邏輯、業(yè)務規(guī)則、數(shù)據(jù)轉(zhuǎn)換、依賴校驗邏輯等。這里要提到的一個概念就是,域模型分為兩個類型,一類是貧血的(Anemic domain model),一類是非貧血的(non-anemic)。貧血的域模型只包含基礎(chǔ)的數(shù)據(jù)信息,而不含有其他數(shù)據(jù)校驗、業(yè)務規(guī)則等邏輯,它更像是一種數(shù)據(jù)庫結(jié)構(gòu)在代碼層面的還原。在貧血域模型設(shè)計中,業(yè)務邏輯通常作為一個獨立的代碼部分,用來轉(zhuǎn)換模型對象的狀態(tài),且各個處理之間可以組合嵌套(用過Redux的同學有沒有覺得很熟悉的感覺?)。在面向?qū)ο笤O(shè)計領(lǐng)域,這通常被視為一個反模式。(OO與FP之間的沖突)
view-mode 作為 view 和 model 的中間人,它的職責是用于處理 view 的邏輯。通常情況下,view-model 與 model 之間的交互是通過調(diào)用 model 類中的方法來完成的。之后 view-model 依據(jù) model 中的數(shù)據(jù)提供一種方便 view 使用的格式。view-model 從 model 中獲取數(shù)據(jù)然后使其對 view 可用的同時,為了讓 view 操作起來更簡單,可能會通過一些方式做數(shù)據(jù)格式轉(zhuǎn)換。view-model 還提供了一些命令的實現(xiàn)讓應用的用戶可以在 view 中使用。比如說,當用戶點擊了 UI 中的一個 button,這個動作可以觸發(fā) view-model 中的一個命令。view-model 同樣有職責去定義一些某些方面會影響 view 展示的邏輯狀態(tài)的變化,比如說一個表明一些操作是掛起的狀態(tài)。
為了讓 view-model 參與到與 view 的雙向數(shù)據(jù)綁定當中,它的屬性必須觸發(fā) PropertyChanged 事件。
(譯者注:后面這兩段是基于 .NET 平臺的具體代碼實踐,換算到 web 領(lǐng)域,基本上說的就是在 VM 中監(jiān)聽數(shù)據(jù)變化,然后做出對應的反應。)
View-model 通過實現(xiàn) INotifyPropertyChanged 接口以及屬性變化時觸發(fā)的 PropertyChanged 事件來滿足這個需求。當屬性發(fā)生變更時,監(jiān)聽者可以適當做回應。
對于集合而言,相應的提供了視圖友好的工具System.Collections.ObjectModel.ObservableCollection
連接 View Models 到 Views譯者:這里提到了一個很重要的事情,就是 vm 獲取到 model 中的數(shù)據(jù)后,可能需要做一些相應的數(shù)據(jù)格式化,以方便 view 使用。在 ng1.x 及 vue1.x 中,這類操作通常是通過在視圖模板上綁定過濾器語法實現(xiàn)的(ng-bind="model | upperCase"),然而 MVVM 定義中,數(shù)據(jù)轉(zhuǎn)換/格式化 的操作本身也是屬于 VM 的一部分。這也是為什么我非常贊同 vue2 中廢除 filter 的一部分原因:Vue 2.0 - Bring back filters please
MVVM 利用了 Silverlight 中的數(shù)據(jù)綁定能力以及行為和事件觸發(fā)器來管理 view 和 view-model 之間的聯(lián)系。這些能力將業(yè)務代碼需要出現(xiàn)在視圖代碼中必要性變得很低。
有很多用來連接 view-model 和 view 的方法,包括直接的關(guān)系以及基于容器的方式。然而,所有的方式共有的一個目標就是,給 view 的 DataContext 屬性分配一個 view-model。
Views 可以與 view models 在獨立代碼文件里建立連接,也可以直接在 view 中。
Code-Behind(獨立代碼)譯者:這里提到了 silverlight 里的 DataContext,換到 web 領(lǐng)域的 MVVM 框架里我們可以理解成作用域,即框架通過給某個視圖的作用域分配一個 view-model 的方式,來完成 view 和 view-model 的銜接。
一個 view 的代碼可以是在獨立代碼文件中,于此同時 view-model 需要分配成它的 DataContext 屬性。這可以是通過一個簡單的 view 初始化一個新的 view-model 然后分配給它的 DataContext 屬性來完成,也可以通過 view 使用控制反轉(zhuǎn)(IOC)容器注入一個 view-model 來實現(xiàn)。
但是,在獨立代碼中 連接一個 view-model 到 view 中的做法是不推薦的,它可能給同時使用 VS 及 MSB(Microsoft Expression Blend?) 設(shè)計軟件的設(shè)計師造成問題。
如果一個 view-model 沒有任何的構(gòu)造器參數(shù),它可以被當做 view 的 DataContext 來實例化。一個通常的實現(xiàn)方法是使用一個 view-model 定位器。這個資源可以公開應用的 view models 作為屬性,從而使得獨立的 view 可以綁定上去。這種方式意味著應用只有一個類用來連接 view models 到 views。此外,它仍然讓開發(fā)者可以自由選擇手動執(zhí)行 view-model 定位器內(nèi)的連接,或者使用一個依賴注入容器。
MVVM 的優(yōu)勢譯者:框架實現(xiàn)指導
MVVM 使得完美的 開發(fā)-設(shè)計 工作流變?yōu)榭赡?,它具備以下?yōu)點:
開發(fā)期間,工程師和設(shè)計師可以更獨立并行的在各自的組件上工作。設(shè)計師可以專注于 view,如果他們使用 Expression Blend,他們可以輕松的生成示例數(shù)據(jù),而這個時候開發(fā)者只需要專注于 view model 和 model 組件。
開發(fā)者可以為 view-model 和 model 編寫單元測試,而不用去管 view。view-model 的單元測試可以完全模擬在 view 上用的那些功能。
由于 view 是完全由 XAML 實現(xiàn)的,這也讓應用的 UI 重新設(shè)計變得簡單,而且還不用去觸碰到邏輯代碼。一個新的版本的 view 應該依然可以與之前已存在的 view-model 一起運行。
如果已經(jīng)存在一個封裝好了已有業(yè)務邏輯的 model ,改這個 model 可能會比較困難或有風險。在這個場景中,view-model 應該作為一個 model 類的適配器,從而避免 model 的代碼需要做大的變動。(譯者注:也就是說,view-model 應該對 model 中的數(shù)據(jù)做一些基礎(chǔ)轉(zhuǎn)換,從而去適配新的 view 或交互邏輯)
更多關(guān)于 MVVM 的信息,參考以下文檔: Implementing the MVVM Pattern.aspx) Advanced MVVM Scenarios.aspx)
譯者按:MVVM 作為2005年微軟提出來的 UI 架構(gòu),我認為在經(jīng)過這么多年的檢驗之后,還是非常值得信賴的。雖然在這一兩年隨著 React 的興起,以及在前端領(lǐng)域“起死回生”的函數(shù)式編程,MVVM 被各種錯誤或‘惡意’的解讀導致其花式被黑。但是在我看來,MVVM 作為一個完整的 GUI 架構(gòu),跟 Flux 流派的數(shù)據(jù)層架構(gòu)本身理念上是并不沖突的。我們依然可以 M/VM 層實踐 Flux。
我認為就前端領(lǐng)域而言,MVVM 最大的意義在于,如果我們能很干凈的分離出應用的 view 和 M/VM,我們就可以使得整個應用的業(yè)務模型能獨立于框架運行。相比于現(xiàn)在換一個框架就重寫一次應用的做法(老實說我受夠了而且覺得沒什么價值),再結(jié)合當前前端‘欣欣向榮’的狀態(tài),如果能做到只需要花費很小的代價,我們就能快速的享受到新技術(shù)帶來的紅利,那基本上就非常美好了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/80554.html
摘要:插件開發(fā)前端掘金作者原文地址譯者插件是為應用添加全局功能的一種強大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實現(xiàn)文件分片斷點續(xù)傳。 Vue.js 插件開發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應用添加全局功能的一種強大而且簡單的方式。插....
摘要:但由于翻譯時草稿只發(fā)布了不到二十天,本文有很好的時效性。語法中同時定義了解析規(guī)則包括異常的處理方式。語法要求聲明,以確保瀏覽器以標準模式渲染頁面。語法中的聲明為,不區(qū)分大小寫。此外,僅允許一些標簽上的屬性設(shè)置。 本文選譯自:W3C Working Group Note: HTML5 Differences from HTML4。 解釋一下W3C Working Group Note,...
摘要:本文介紹一些來自投資銀行的針對三年以上經(jīng)驗的開發(fā)人員面試題。第七題和這兩個方法有什么不同答案本題取自我的投資銀行針對有經(jīng)驗的開發(fā)者的五十個多線程面試題列表??偨Y(jié)以上就是投資銀行通常會出的面試題。 原文地址: https://dzone.com/articles/10... 有為數(shù)不少的開發(fā)者希望能在像 Barclays、Credit Suisse、Citibank 等等那樣的投資銀行做...
閱讀 3656·2021-11-24 10:19
閱讀 3803·2021-09-30 09:47
閱讀 1371·2019-08-30 15:56
閱讀 859·2019-08-29 15:11
閱讀 965·2019-08-29 13:43
閱讀 3645·2019-08-28 18:25
閱讀 2222·2019-08-26 13:27
閱讀 1492·2019-08-26 11:44