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