郭寧遠,徐建良
?。ㄖ袊Q蟠髮W 信息科學與工程學院,山東 青島 266100)
摘要:針對財務預算的領域概念和復雜需求,將一種模型驅(qū)動的開發(fā)方式實踐于預算管理系統(tǒng)的設計與實現(xiàn),使開發(fā)人員脫離復雜的數(shù)據(jù)庫設計,更加專注領域概念的消化、模型和數(shù)據(jù)傳輸對象的創(chuàng)建。給出了預算管理系統(tǒng)的整體說明和框架的總體結構設計,并以開發(fā)順序依次介紹了各層的設計與實現(xiàn),最后結合系統(tǒng)快速上線的效果說明了這種模型驅(qū)動開發(fā)方式的可行性、便利性和快捷性。
關鍵詞:預算管理; 信息系統(tǒng); Entity Framework; Model First; 數(shù)據(jù)傳輸對象; 多層架構; JSON;
中圖分類號:TP311.11文獻標識碼:ADOI: 10.19358/j.issn.16747720.2016.22.003
引用格式:郭寧遠,徐建良.模型驅(qū)動的預算管理系統(tǒng)設計與實現(xiàn)[J].微型機與應用,2016,35(22):11-14.
0引言
在面對某領域內(nèi)的專業(yè)概念和復雜需求時,將新知識吸收轉(zhuǎn)化為軟件產(chǎn)品對于軟件開發(fā)人員來說是一項艱巨的任務。一方面在此過程中若軟件開發(fā)人員對領域?qū)<业男枨罄斫獠煌笍?,將會導致工作重心的偏離、軟件交付期延長、需求頻繁變更等影響軟件開發(fā)和交付的嚴重后果。另一方面,軟件開發(fā)人員更偏向于使用技術來解決領域問題,比如沉溺于設計完美的數(shù)據(jù)庫來滿足需求,而這往往是事倍功半的方法。
基于模型的開發(fā)方式提高了代碼本身的溝通能力。模型是一種知識形式,它對知識進行有選擇的簡化和有目的的結構化[1]。使用適當?shù)哪P筒⒛P拓灤┯谡麄€開發(fā)過程,可以使軟件開發(fā)人員專注于需求相關的信息,簡化與領域?qū)<业臏贤?,使知識表達更加準確,更加貼合需求。
Entity Framework是微軟研發(fā)的一種對象關系映射組件(ORM),它可以在關系型數(shù)據(jù)庫和對象之間產(chǎn)生自動映射[2]。在Entity Framework 6.x版本中提供三種開發(fā)模式:Code First、Database First和Model First[3]。本文將利用Model First開發(fā)模式,以模型的構建為中心,通過模型驅(qū)動開發(fā),數(shù)據(jù)庫由模型生成,開發(fā)人員只需將關注點放在領域模型和數(shù)據(jù)傳輸對象(DTO)的轉(zhuǎn)化上即可。
1系統(tǒng)整體說明
1.1系統(tǒng)基本流程
圖1預算新建及審核流程系統(tǒng)主要分為兩個業(yè)務流程,即預算業(yè)務流程和預算調(diào)整業(yè)務流程。
預算業(yè)務流程如圖1所示,起于專家對已經(jīng)立項的項目添加預算,終于財務處管理員審核通過預算。
預算調(diào)整流程如圖2所示,貫穿于整個項目進行過程中,當本次預算出現(xiàn)改變等需要調(diào)整的情況時,專家提出調(diào)整請求,由科技處管理員審核。
1.2系統(tǒng)模塊劃分
系統(tǒng)以項目預算業(yè)務流程為核心,以數(shù)據(jù)查詢、審核、分析為重心,包括基本信息維護、預算管理、預算調(diào)整管理、子課題管理、預算審核管理、調(diào)整審核管理、統(tǒng)計報表等功能。系統(tǒng)模塊如圖3所示。
模塊功能簡要說明如下:
(1)基本信息維護:包括用戶、角色、權限、界面等用戶關聯(lián)信息管理,系統(tǒng)使用基于角色的訪問控制方法,可便捷簡單地處理用戶與權限之間關系;維護批復預算基本增、刪、改、查操作。
(2)預算管理:包括專家對負責項目預算信息的基本處理,如新建、修改、查看、保存、提交、報表導出等,以及該項目子課題的科目預算制定與子課題指派等功能。
(3)預算調(diào)整管理:預算調(diào)整是項目在執(zhí)行過程中,專家對承擔的項目預算進行調(diào)整工作,包括調(diào)整的新建、修改、查看、保存、提交等工作,在調(diào)整過程中,可以添加新的子課題;專家亦可以查閱項目之前的每一次調(diào)整。
(4)子課題管理:專家可對子課題憑單號、賬本號進行編輯,也可查看參與的項目與子課題的預算分配情況。
(5)預算審核管理:財務處管理員對專家提交的項目預算進行審核。
(6)調(diào)整審核管理:科技處管理員對專家提交的預算調(diào)整進行審核。
(7)預算數(shù)據(jù)統(tǒng)計:提供子課題數(shù)據(jù)的導出功能,將系統(tǒng)中的數(shù)據(jù)根據(jù)財務處相關要求導出一定格式的DBF文件,供財務處統(tǒng)計、分析、導入等使用。
2系統(tǒng)結構設計與各層次的實現(xiàn)
系統(tǒng)采用B/S架構,客戶端只需一個瀏覽器,就可以通過Web服務器與服務器端進行數(shù)據(jù)交互[4]。按照高效、易維護的原則將系統(tǒng)分為展示層、服務層、數(shù)據(jù)轉(zhuǎn)化層、業(yè)務邏輯層、領域模型層、DTO模型層六個層次,如圖4所示。
系統(tǒng)打破傳統(tǒng)的以業(yè)務邏輯為中心的開發(fā)模式,轉(zhuǎn)為以領域模型和DTO模型為中心的開發(fā)模式,使前后端開發(fā)人員更專注處理用戶的需求,更快地理解、吸收領域知識,從而構建高質(zhì)量、易維護的軟件產(chǎn)品。這種開發(fā)模式的順序為:
(1)開發(fā)人員與領域?qū)<疫M行交流溝通,根據(jù)需求確定系統(tǒng)的領域模型結構,再根據(jù)領域模型構建前后臺傳輸?shù)腄TO模型。
(2)確定好領域模型和DTO模型,前端的開發(fā)只需關注與后端服務器交互的DTO模型,根據(jù)用戶對界面的要求和各個界面的DTO模型構建展示層中的各個界面。
(3)后端服務器端只需關注領域模型與DTO模型之間的轉(zhuǎn)化,根據(jù)需求的轉(zhuǎn)化規(guī)則完成業(yè)務邏輯層的編寫。
(4)根據(jù)前后臺約定的數(shù)據(jù)傳輸格式,完成數(shù)據(jù)轉(zhuǎn)化層編寫。
(5)編寫服務層WebService供前端展示層調(diào)用。
開發(fā)順序如圖5所示。
2.1領域模型層設計實現(xiàn)
領域模型層是系統(tǒng)的核心層,是連接整個系統(tǒng)的橋梁。在此層次中軟件開發(fā)人員利用Entity Framework的Model First開發(fā)模式構建模型,模式的核心為EDM(Entity Data Model)技術,EDM提供圖形化的設計界面,將模型設計和代碼實現(xiàn)綁定,通過與領域?qū)<业慕涣?,利用頭腦風暴等活動將系統(tǒng)的領域概念和復雜需求等知識消化并提煉到模型當中,并通過不斷地修改和調(diào)整模型使之更滿足預算系統(tǒng)的需求,最終確定出整個系統(tǒng)的領域模型。
確定好領域模型后,開發(fā)人員只需保存模型,即可根據(jù)模型中屬性和實體間關聯(lián)等信息生成所有實體對象,并生成一個繼承于DbContext基類的數(shù)據(jù)庫上下文對象[5]。其中Entity Framework庫里面的DbContext基類為操控實體對象執(zhí)行上下文環(huán)境, 提供所需的架構和映射元數(shù)據(jù)(Meatadata)、數(shù)據(jù)庫鏈接,同時還包括對象緩存、跟蹤狀態(tài)和關聯(lián)管理等功能[3]。
保存好模型并生成實體和數(shù)據(jù)庫上下文后,在模型中選擇“根據(jù)模型生成數(shù)據(jù)庫”,配置好連接字符串,即可從模型映射到相應的數(shù)據(jù)庫中,使開發(fā)人員擺脫使用復雜的數(shù)據(jù)庫管理工具進行數(shù)據(jù)庫設計和實現(xiàn)的工作。
以預算及其審核模塊為例,構建圖6所示模型。
2.2DTO模型層設計實現(xiàn)
領域模型層完成后,開發(fā)人員的下一個關注點應是數(shù)據(jù)的傳輸,也就是DTO模型的構建。
DTO(Data Transfer Object)即數(shù)據(jù)傳輸對象,是一種用來在多層架構軟件系統(tǒng)中層間交換數(shù)據(jù)的對象。DTO的提出是為了在客戶端和服務器端交換大量的數(shù)據(jù),而無需多個細粒度的調(diào)用,從而減少遠程調(diào)用的數(shù)目 ,避免相關的網(wǎng)絡負載[6]。
開發(fā)人員可根據(jù)領域模型和原型界面構建DTO模型。在預算管理系統(tǒng)框架中,業(yè)務邏輯層根據(jù)每個界面的數(shù)據(jù)需求從領域模型層中取出相應的數(shù)據(jù)并組合成與需求數(shù)據(jù)相對應的DTO對象,然后交由數(shù)據(jù)轉(zhuǎn)化層;或者由數(shù)據(jù)轉(zhuǎn)化層將服務層傳來的數(shù)據(jù)轉(zhuǎn)化成DTO對象,然后交由業(yè)務邏輯層進行處理。所以,DTO模型是前后臺數(shù)據(jù)傳輸?shù)暮诵?,確定好DTO模型后,向下關注業(yè)務邏輯層的編寫,向上關注數(shù)據(jù)轉(zhuǎn)化層、服務層、展示層的編寫,并且可以同時進行,大大節(jié)約了時間成本。
以預算審核列表的顯示為例,DTO模型的示例代碼如下:
public class BudgetAuditListDTO{
public List<BudgetAuditVO> budgetAuditList { get; set; }
}
public class BudgetAuditVO{
public int projectid { get; set; }
public long totalamounts { get; set; }
public long outeramounts { get; set; }
public string prjmanagername { get; set; }
public string prjstate { get; set; }
}
2.3業(yè)務邏輯層設計實現(xiàn)
領域模型層和DTO模型層均構建完畢后,業(yè)務邏輯層的職責是領域模型和DTO模型之間的轉(zhuǎn)化。語言集成查詢(Language Integrated Query,LINQ)是一組語言特性和API,LINQ to Entities提供了查詢關系數(shù)據(jù)庫中的實體模型的方式[7]。在此層次中,系統(tǒng)使用LINQ to Entities技術,從領域模型實體中進行數(shù)據(jù)的增、刪、改、查。
以“我的子課題列表”的顯示為例,系統(tǒng)在接收到前臺的數(shù)據(jù)請求后,業(yè)務邏輯層使用LINQ to Entities技術將數(shù)據(jù)從數(shù)據(jù)庫中取出。示例代碼如下:
varquery = from miss in
database.MissionSet.OfType<InnerMission>()
where miss.ManagerId == userId
select new {
MissionId = miss.Id,
ProjectId = miss.ProjectId,
MissionName = miss.MissionName
};
查詢結束后,將結果根據(jù)列表所對應的DTO模型進行DTO模型屬性的賦值和組合,示例代碼如下:
foreach(var q in queryList){
MyMissionListVO mmlVO = new MyMissionListVO(){
missionid = q.MissionId,
projectid = q.ProjectId,
mssname = q.MissionName};
this.missionListDTO.Add(mmlVO);
}
經(jīng)過上述步驟,業(yè)務邏輯層就完成了領域模型與DTO模型的轉(zhuǎn)化。
2.4數(shù)據(jù)轉(zhuǎn)化層和服務層設計實現(xiàn)
預算管理系統(tǒng)中,前后臺數(shù)據(jù)是通過JSON(JavaScript Object Notation)格式來傳輸?shù)?。JSON是一種輕量級的數(shù)據(jù)傳輸格式,易于閱讀和編碼,可以在多種語言之間進行數(shù)據(jù)交換[8]。數(shù)據(jù)轉(zhuǎn)化層將業(yè)務邏輯層傳來的DTO對象序列化成JSON格式的數(shù)據(jù),或者根據(jù)服務層傳來的JSON格式的數(shù)據(jù)反序列化成DTO對象。
預算管理系統(tǒng)的數(shù)據(jù)轉(zhuǎn)化層使用JSON.NET技術實現(xiàn)JSON的序列化和反序列化。使用JSON.NET技術可以自動進行JSON的序列化和反序列化,是.NET框架下一款功能強大且高效的開源序列化和反序列化工具[9]。
以子課題更新功能為例,先將服務層傳來的子課題信息反序列化為DTO對象,交由業(yè)務邏輯層保存后,將返回的子課題再序列化為JSON返回給服務層。示例代碼如下:
MissionDTO missionDTO=
JsonConvert.DeserializeObject<AddAndReturnMissionsBusin-ess>(json);
missionDTO = aarmb.SaveAndReturn(database);
json =
JsonConvert.SerializeObject(missionDTO,Formatting.Indented);
預算管理系統(tǒng)的服務層提供WebService供展示層調(diào)用,負責接收展示層發(fā)來的請求,并將數(shù)據(jù)傳給數(shù)據(jù)轉(zhuǎn)化層。
以子課題更新的WebService為例,服務層接收到前端的請求后,實例化數(shù)據(jù)轉(zhuǎn)化層的對象,將JSON等數(shù)據(jù)傳給數(shù)據(jù)轉(zhuǎn)化層。示例代碼如下:
public class AddAndReturnMissions : WebServiceBase{
?。踂ebMethod]
public void SaveAndReturn(string mssParam){
AddAndReturnMissionsTrans aarmT =
new AddAndReturnMissionsTrans();
aarmT.SaveAndReturn(Database, mssParam);}
}
2.5展示層設計實現(xiàn)
預算管理系統(tǒng)的展示層采用ExtJS富客戶端框架。ExtJS是基于JavaScript語言開發(fā)的客戶端Ajax框架,優(yōu)點是與后臺技術無關,而且瀏覽器兼容性較強[10]。
在確定完領域模型和DTO模型后,軟件的前臺開發(fā)人員利用ExtJS后臺技術無關的優(yōu)點,并利用之前確定好的DTO模型和需求分析階段的原型界面即可編寫前端代碼。
預算管理系統(tǒng)利用ExtJS提供的視圖、表單、列表、表格等組件構建友好、美觀的用戶界面,并通過ExtJS提供的Ajax功能與后臺進行交互。以財務處管理員登錄后的界面為例,用戶登錄成功后,系統(tǒng)發(fā)起主界面的Ajax請求,取得相應數(shù)據(jù)并渲染到用戶界面。示例界面如圖7所示。
3結論
模型驅(qū)動的開發(fā)方式適用于需求急迫、領域概念復雜、對軟件質(zhì)量要求高的軟件研發(fā)。本文針對預算管理系統(tǒng)的復雜需求,展示了模型驅(qū)動開發(fā)方式的實踐,軟件開發(fā)人員使用模型作為一種語言,與領域?qū)<医涣鞑⒉粩喔倪M模型,快速地明確需求,使領域知識精確地消化于模型中。在明確模型之后,以模型為橋梁,使系統(tǒng)框架中各個層次并行開發(fā),大大節(jié)約了時間成本。并行的開發(fā)使開發(fā)人員專注于各層次的功能需求,提高了代碼的質(zhì)量。通過模型,軟件開發(fā)人員還可以挖掘潛在需求進行深度開發(fā),進一步改進軟件的性能。
目前預算系統(tǒng)已上線使用,其在短期內(nèi)的上線使用和其穩(wěn)定性證明了文中介紹的基于模型驅(qū)動的開發(fā)方式的可行性、便利性和快捷性。
參考文獻
?。?] EVANS E.領域驅(qū)動設計[M].趙俐,盛海艷,劉霞,等,譯.北京:人民郵電出版社, 2010.
?。?] 黃睿.基于Java技術的ORM工具接口的設計與實現(xiàn)[D]. 長春:吉林大學,2012.
?。?] 沈霞菲, 王建中.基于.NET Entity Framework數(shù)據(jù)庫訪問機制的設計與應用[J].現(xiàn)代電子技術,2014(24):5-8.
?。?] 谷惠敏.基于Web的高校檔案管理系統(tǒng)設計[J].現(xiàn)代電子技術,2015(21):139-141.
?。?] LERMAN J,MILLER R.Programming entity framework: DbContext[M].O’reilly Media,2012.
[6] 朱彬, 陳志軍.DTO 模式的研究及對其實現(xiàn)的改進[J].沈陽航空航天大學學報,2004,21(4):53-55.
?。?] 郭睿志, 邊力, 譚龍丹,等.數(shù)據(jù)庫查詢中LINQ to Entities應用研究[J].軟件導刊,2014(1):122-124.
?。?] 高靜, 段會川.JSON數(shù)據(jù)傳輸效率研究[J].計算機工程與設計,2011,32(7):2267-2270.
?。?] ALLEN J.JsonNET claims significant performance improvements over other.NET Serializers[J].InfoQ,2010.
[10] 易俗, 殷慧文.基于ExtJS的富客戶端聯(lián)通分銷商管理系統(tǒng)設計[J].遼寧大學學報(自然科學版),2015,42(2):143-149.