王躍
(四川大學 計算機學院,四川成都 610065)
MVVM模型,是由微軟開發(fā)人員為了降低復雜用戶界面程序的開發(fā)復雜性而提出的一種前端設計模式[1]。作為MVC經(jīng)典模型的擴展、升級,MVVM實現(xiàn)了視圖層(View)與數(shù)據(jù)模型層(Model)的完全解耦,可以使系統(tǒng)開發(fā)者和設計者完全獨立、并行地工作。因為MVVM的諸多優(yōu)點,目前非常多的主流用戶界面程序開發(fā)平臺都采用該模型。
但在實際應用程序開發(fā)過程中,我們發(fā)現(xiàn),采用傳統(tǒng)MVVM模型進行設計開發(fā)的程序不能很好地適應軟件需求變更,也不能準確、完整地實現(xiàn)需求復雜性較高的系統(tǒng)[2]。分析原因可知,MVVM模型的關注點是業(yè)務數(shù)據(jù),是數(shù)據(jù)驅(qū)動的開發(fā)模式,并沒有從業(yè)務領域解決開發(fā)人員與領域?qū)<抑g的溝通問題。
對此,本文在用戶界面程序MVVM模型中,加入領域驅(qū)動設計的思想,提出了領域驅(qū)動的MVVM架構(gòu)設計模型。將軟件分析與設計的關注點引導到業(yè)務上來,使用領域模型作為分析與設計的通用語言(Ubiquitous Language)。領域驅(qū)動的MVVM模型,以領域模型為核心,指導相關人員以領域驅(qū)動的思想進行系統(tǒng)分析、設計、開發(fā)工作,形成了統(tǒng)一的系統(tǒng)語言(Ubiquitous Language),使最終實現(xiàn)的軟件真正滿足需求。
本章1.1節(jié)和1.2節(jié)分別介紹了MVVM模型和領域驅(qū)動設計,為下文提出領域驅(qū)動的MVVM架構(gòu)模型奠定了理論基礎。
MVVM中很重要的一項技術,即“數(shù)據(jù)綁定(Data Binding)”技術[3]。數(shù)據(jù)綁定技術實現(xiàn)了View與Model的完全解耦。其中View與ViewModel是一一對應的,業(yè)務邏輯保存在ViewModel中,作為領域數(shù)據(jù)對象的Model是“貧血”模型。MVVM架構(gòu)沒有從整體業(yè)務領域的交互方面進行充分設計,當涉及多個領域?qū)ο蠼换r,會出現(xiàn)多個ViewModel互相調(diào)用、軟件邏輯混亂的情況。因此,隨著業(yè)務需求越來越復雜,業(yè)務領域內(nèi)部關聯(lián)性的提高,軟件分析、設計、開發(fā)的復雜性都會提高[4]。
Eric Evans將領域驅(qū)動設計架構(gòu)分為四層:用戶界面層、應用層、領域?qū)雍突A設施層[1]。
其中,領域?qū)訛闃I(yè)務軟件的核心。負責表達業(yè)務概念、業(yè)務狀態(tài)信息及業(yè)務規(guī)則。領域?qū)影I域模型。領域驅(qū)動設計中,領域模型是由基本的模型元素構(gòu)成。Eric Evans 提出了6種領域模型元素:實體、值對象、聚合、領域服務、工廠和倉儲。其中,實體、值對象和聚合為領域?qū)ο?包含了領域業(yè)務數(shù)據(jù)和流程,即整個領域知識。
在標準MVVM模型基礎上,本文引入了領域驅(qū)動設計的思想。使得領域驅(qū)動的MVVM設計模型(DDMVVM)既繼承了MVVM模型優(yōu)點,又遵循領域驅(qū)動設計思想。

圖1 MVVM架構(gòu)各層結(jié)構(gòu)
本文提出的DDMVVM模型在需求獲取、系統(tǒng)設計階段,能夠根據(jù)客戶需求,準確、完整地獲取領域知識,并正確地抽象出領域模型,實現(xiàn)領域模型中各要素之間正確的依賴、分治。領域?qū)<摇⒃O計人員、開發(fā)人員以以領域模型作為“通用語言”(Ubiquitous Language)進行溝通,不斷地迭代開發(fā)、優(yōu)化領域模型[5][6]。
DDMVVM的系統(tǒng)架構(gòu),在遵循領域驅(qū)動設計分層架構(gòu)基礎上,結(jié)合用戶前端程序開發(fā)的MVVM架構(gòu)層次要求,實現(xiàn)了DDMVVM模型整體架構(gòu)的設計。
如圖2所示,將DDD的各模型元素與MVVM三層做映射。分別在View、ViewModel和Model層,實現(xiàn)領域驅(qū)動的模型元素。在領域?qū)蛹赐瓿蓸I(yè)務領域的邏輯處理能力[3]。
其中,“Repository倉儲”,即為與后端程序交互層,其主要功能為:1.將領域?qū)訑?shù)據(jù)傳到后端,進行持久化;2.響應“領域?qū)印闭埱?從后端程序獲取數(shù)據(jù)作為領域數(shù)據(jù)。
對照“圖1 MVVM整體架構(gòu)圖”,DDMV VM的改進之處:
(1)DDMVVM將領域相關的業(yè)務邏輯放在了“Model層”,即業(yè)務邏輯分布在各自領域?qū)ο笾?實現(xiàn)了“充血模型”。
(2)“ViewModel層”作為協(xié)調(diào)角色存在,負責協(xié)調(diào)相關聯(lián)的多個領域?qū)ο筇幚?不保存領域相關業(yè)務邏輯代碼,只保存系統(tǒng)流轉(zhuǎn)狀態(tài);MVVM中的“數(shù)據(jù)綁定”和“命令”技術,由“ViewModel層”實現(xiàn)。
(3)“View層”不需要實現(xiàn)與Model層關聯(lián)的邏輯,由“ViewModel層”實現(xiàn)View與Model的一對一或多對一關聯(lián)。
(4)Model層作為核心,實現(xiàn)了“充血”的Model層。
(5)工廠和倉儲位于模型層,分別負責領域?qū)ο髣?chuàng)建和管理工作。
這樣,避免了標準MVVM模型中出現(xiàn)的因業(yè)務邏輯交互而出現(xiàn)的邏輯混亂的情況。

圖2 DDMVVM模型整體架構(gòu)圖

圖3 DDMVVM Framework框架結(jié)構(gòu)示意圖
DDD提供了戰(zhàn)略設計和戰(zhàn)術設計兩種領域模型設計方式。
戰(zhàn)略設計幫助我們從更高的宏觀層面把握整體業(yè)務領域,正確的劃分邏輯上相互獨立的子領域,并按照“一個子領域?qū)粋€BC”的標準,為每個子領域定義對應的一個BC。在子領域內(nèi),使用通用語言明確定義BC邊界內(nèi)各個概念、術語、定義。
在限界上下文中,使用戰(zhàn)術設計方法,設計實現(xiàn)領域模型,創(chuàng)建領域模型中的各個構(gòu)成元素,以表示子領域中的所有領域概念。根據(jù)Eric Evans提出的領域模型構(gòu)成元素,DDMVVM模型的設計,也由6種元素構(gòu)成:實體、值對象、聚合、領域服務、工廠和倉儲。
DDMVVM模型可以有效指導相關人員以領域模型為核心,進行系統(tǒng)分析、設計和開發(fā)工作。本文不僅提出了DDMVVM模型,而且以該模型為指導,在移動開發(fā)平臺下實現(xiàn)了一個具體的開發(fā)框架DDMVVM Framework。該框架基于JS語言,將移動開發(fā)平臺中的開發(fā)代碼、功能組件進行重構(gòu),使系統(tǒng)的設計、開發(fā)過程符合領域驅(qū)動設計的規(guī)范。
DDMVVM開發(fā)框架:
該框架的設計目標是在實際項目開發(fā)中,引導相關人員以DDMVVM模型為指導,規(guī)范地設計、開發(fā)方式實現(xiàn)系統(tǒng),以提高系統(tǒng)分析、設計和開發(fā)的效率。
如圖3所示,該框架編程語言為移動開發(fā)平臺下的JS語言,具體實現(xiàn)了圖2所示DDMVVM架構(gòu)中各層領域模型元素,并實現(xiàn)了面向?qū)ο蟮某绦蛟O計。
本文以第3章提出的DDMVVM模型為指導,對之前在移動開發(fā)平臺下實現(xiàn)的一個政務系統(tǒng)項目進行了設計重構(gòu)、代碼重構(gòu)。該項目采用第4章提出的DDMVVM Framework開發(fā)框架進行具體設計、開發(fā)實現(xiàn)。
將新舊系統(tǒng)進行對比后發(fā)現(xiàn),采用DDMVVM設計開發(fā)的新系統(tǒng)要比之前舊系統(tǒng)實現(xiàn)的系統(tǒng)架構(gòu)更優(yōu)秀,新系統(tǒng)在系統(tǒng)完成效率、代碼性能及可維護性等方面都有了顯著提高。
本文提出了適用于用戶界面應用程序開發(fā)的一種新的設計模型:領域驅(qū)動的MVVM設計模型(DDMVVM)。并以該模型為指導,在移動開發(fā)平臺下實現(xiàn)了具體的開發(fā)框架DDMVVM Framework。
[1]EricEvans,埃文斯,趙俐,等.領域驅(qū)動設計:軟件核心復雜性應對之道[M].人民郵電出版社,2016.
[2]李引,袁峰.基于領域驅(qū)動設計的應用系統(tǒng)模型[J].計算機工程與應用,2013,49(16):1-8.
[3]黃強,王薇,倪少權(quán).基于SOA和DDD的鐵水聯(lián)運信息平臺構(gòu)架設計[J].計算機應用與軟件,2013,30(6):124-126.
[4]陳明,李猛坤,張強.一種基于擴展MVVM模式的SaaS面向服務計算模型[J].微電子學與計算機,2010,27(8):27-30.
[5]劉立.MVVM模式分析與應用[J].微型電腦應用,2012,28(12):57-60.
[6]Kouraklis J.MVVM as Design Pattern[M]//MVVM in Delphi.Apress,2016.