日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

一堂如何提高代碼質(zhì)量的培訓(xùn)課 之 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)

系統(tǒng) 1701 0

終于到了該說說領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的時(shí)候了。我們?cè)谶@場(chǎng)關(guān)于代碼質(zhì)量的討論中,從代碼可讀性開始,討論了代碼復(fù)用性、設(shè)計(jì)模式,然后探討了職責(zé)驅(qū)動(dòng)設(shè)計(jì)。代碼可讀性是對(duì)代碼質(zhì)量最基本的要求,可惜我們?nèi)杂凶龅貌粔虻模词鼓切╅_發(fā)程序很多年的老程序員)。代碼復(fù)用是提高代碼質(zhì)量的最初級(jí)階段,但是在一個(gè)多人開發(fā)的項(xiàng)目團(tuán)隊(duì)中,圍繞代碼復(fù)用值得討論的問題依然非常多,它依然是一個(gè)非常復(fù)雜的問題,甚至有時(shí)它不再僅僅是一個(gè)技術(shù)問題,而是一個(gè)管理問題。唉,提高代碼質(zhì)量的道理漫漫兮同志們要上下而求索。一個(gè)比較成功的保證代碼質(zhì)量的管理模式就是代碼復(fù)查。讓一些有經(jīng)驗(yàn)的程序員定期去復(fù)查那些初級(jí)程序員的代碼,指導(dǎo)他們的開發(fā),被認(rèn)為是成功的,但也代價(jià)巨大的。

然而,在這場(chǎng)關(guān)于代碼質(zhì)量的討論中,我認(rèn)為,最終的終極目標(biāo)毫無疑問應(yīng)當(dāng)是“領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)”。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)可以快速而根本地提高我們的代碼質(zhì)量,舉一個(gè)最近發(fā)生的一件事情也許可以深刻地說明這一點(diǎn)。前不久,我將一個(gè)開發(fā)任務(wù)交給了我的一個(gè)手下。一周后,當(dāng)我對(duì)他的代碼進(jìn)行復(fù)查的時(shí)候,我驚呆了。我甚至不能提出任何的建議來優(yōu)化他的代碼。隨后,我花了半個(gè)小時(shí)的時(shí)間與他一起進(jìn)行了一次領(lǐng)域模型分析,將他開發(fā)的這個(gè)模塊用領(lǐng)域模型繪制了一個(gè)草圖。隨后的數(shù)日,他照著這個(gè)圖紙重新進(jìn)行了編碼。當(dāng)我再次復(fù)查他的代碼時(shí),我忍不住笑了。在短短的一周時(shí)間內(nèi)能讓一個(gè)人的代碼質(zhì)量判若兩人,這不得不說是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)帶給我們的震撼。

但是,在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)之前,我用大量篇幅講解了職責(zé)驅(qū)動(dòng)設(shè)計(jì)。職責(zé)驅(qū)動(dòng)設(shè)計(jì)是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的理論基礎(chǔ),領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)是職責(zé)驅(qū)動(dòng)設(shè)計(jì)的最佳實(shí)踐。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)要求我們以領(lǐng)域模型作為我們分析與開發(fā)的核心,為什么?因?yàn)槲覀兊脑O(shè)計(jì)應(yīng)當(dāng)與現(xiàn)實(shí)世界保持“低表示差異”。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)強(qiáng)調(diào)所有的領(lǐng)域?qū)ο髴?yīng)當(dāng)以現(xiàn)實(shí)世界作為模板,為其定義和分配行為,為什么?因?yàn)槲覀兊脑O(shè)計(jì)應(yīng)當(dāng)以職責(zé)為中心,按職責(zé)分配行為,分配行為的原則可以參照“信息專家”模式。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)并不是橫空出世的,而是在職責(zé)驅(qū)動(dòng)設(shè)計(jì)的基礎(chǔ)之上發(fā)展的。理解職責(zé)驅(qū)動(dòng)設(shè)計(jì)可以促進(jìn)我們對(duì)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的理解,然而非常遺憾的是,它卻長期游離于我們的視線之外。

?

低表示差異與領(lǐng)域模型

我在前面的“職責(zé)驅(qū)動(dòng)設(shè)計(jì)”部分已經(jīng)討論了“低表示差異”。用一句簡(jiǎn)短的話說,在我們的分析設(shè)計(jì)中,軟件世界始終應(yīng)當(dāng)與現(xiàn)實(shí)世界保持“低表示差異”。如何保持低表示差異呢?答案就是領(lǐng)域模型分析。

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),其名稱中,將“領(lǐng)域( Domain )”這個(gè)詞放在了最顯著的位置上,為什么呢?因?yàn)樗睦碚摵诵木褪穷I(lǐng)域。在需求分析和設(shè)計(jì)階段使用領(lǐng)域模型與客戶進(jìn)行軟件需求的討論。在這個(gè)階段,領(lǐng)域模型是最重要的一個(gè)驗(yàn)收成果,沒有完成領(lǐng)域模型分析,這個(gè)階段就永遠(yuǎn)不算結(jié)束。在軟件開發(fā)階段采用領(lǐng)域模型作為核心設(shè)計(jì)圖紙指導(dǎo)設(shè)計(jì)開發(fā)。領(lǐng)域模型怎樣設(shè)計(jì)則我們的軟件系統(tǒng)就怎樣設(shè)計(jì),軟件系統(tǒng)中的最主要軟件類都是源自領(lǐng)域模型中定義的領(lǐng)域?qū)ο蟆T谶\(yùn)行維護(hù)及二次開發(fā)階段,領(lǐng)域模型就如同房屋建筑中的設(shè)計(jì)圖紙,它成為運(yùn)行維護(hù)人員和二次開發(fā)人員熟悉和理解軟件系統(tǒng)的核心線索??傊陬I(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中,領(lǐng)域模式成為最最核心的內(nèi)容。所以我們應(yīng)當(dāng)首先理解什么是領(lǐng)域模型。

領(lǐng)域模型是對(duì)現(xiàn)實(shí)世界中某個(gè)業(yè)務(wù)領(lǐng)域的抽象。我們?cè)O(shè)計(jì)的軟件不是對(duì)所有現(xiàn)實(shí)世界的模擬,而是對(duì)某個(gè)領(lǐng)域的模擬,譬如財(cái)務(wù)領(lǐng)域、稅務(wù)領(lǐng)域、企業(yè)管理領(lǐng)域等等。這個(gè)領(lǐng)域我們稱之為“業(yè)務(wù)領(lǐng)域”,而在這個(gè)領(lǐng)域里工作,并熟悉掌握這個(gè)領(lǐng)域中所有知識(shí)的人我們稱之為“領(lǐng)域?qū)<摇薄N覀兊姆治龊驮O(shè)計(jì)人員對(duì)業(yè)務(wù)領(lǐng)域的熟悉和理解的程度,往往決定我們的軟件是否滿足客戶需求,也往往就決定了我們的軟件是否成功。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)理論要求我們?cè)谛枨蠓治鲭A段必須非常深入地理解業(yè)務(wù)領(lǐng)域,采用的方式就是領(lǐng)域模型分析。同時(shí),在這樣一個(gè)過程中,應(yīng)該有領(lǐng)域?qū)<覅⑴c,甚至成為分析設(shè)計(jì)中的一個(gè)成員。

過去我們使用用例模型與領(lǐng)域?qū)<医涣?,直到現(xiàn)在我們依然還在這樣做。用例模型分析是我們分析設(shè)計(jì)的方法之一,但現(xiàn)在我們又有了一個(gè)新的強(qiáng)有力的工具,那就是領(lǐng)域模型分析。與用例模型比較,領(lǐng)域模型更加直觀,可以更加立體地描述現(xiàn)實(shí)世界。如果說過去的需求設(shè)計(jì)文檔是二維世界,用例模型只是二維半,領(lǐng)域模型才是真三維世界。領(lǐng)域模型是一大堆的類圖,它描述的是業(yè)務(wù)領(lǐng)域中的各個(gè)事物,以及事物與事物之間的關(guān)系。

從業(yè)務(wù)領(lǐng)域中獲取知識(shí)

說了這么多東西,現(xiàn)在讓我們來點(diǎn)兒實(shí)在的東西吧:如何進(jìn)行領(lǐng)域模型分析?建立領(lǐng)域模型需要從業(yè)務(wù)領(lǐng)域中獲取素材。獲取領(lǐng)域模型所需素材通常有兩個(gè)途徑:與領(lǐng)域?qū)<业默F(xiàn)場(chǎng)交流會(huì)中獲得,和從用例模型的各個(gè)流程中提取名詞或名詞短語獲得。我們將這些獲取的素材經(jīng)過加工,形成我們?cè)陬I(lǐng)域模型中的一個(gè)又一個(gè)的類,這些類我們稱之為概念類?,F(xiàn)在的問題是,哪些應(yīng)當(dāng)成為領(lǐng)域模型中的概念類呢?如果我引用一堆定義和準(zhǔn)則,并不能讓你清楚明了,也許一個(gè)生動(dòng)的比喻更能夠讓你理解深刻。需求分析有時(shí)候就像一部部動(dòng)畫劇,而那些枯燥乏味的概念,紛繁復(fù)雜的流程,在這些動(dòng)畫劇中似乎都突然活了,個(gè)個(gè)都有語言有性格。在這些動(dòng)畫劇中扮演的所有角色,就是我們需要的概念類。而他們做的所有動(dòng)作,就是用例模型中的所有流程。

1 )在業(yè)務(wù)討論會(huì)中繪制領(lǐng)域模型

運(yùn)用我曾經(jīng)一篇文章中的實(shí)例來更加生動(dòng)地描述這樣一個(gè)過程吧:

在一個(gè)陽光明媚的下午,我們一個(gè)個(gè)西裝革履、精神抖擻地來到了客戶的辦公現(xiàn)場(chǎng)。在一個(gè)明亮的會(huì)議室里,寬大深褐色的橢圓木桌旁已經(jīng)聚集了十來個(gè)業(yè)務(wù)人員??吹轿覀冞M(jìn)來,大家握手問候。相繼就座后,互相介紹,往來寒暄,嘮嘮家常。共同的家鄉(xiāng),或熟或不怎么熟的某個(gè)人,都可能成為拉近彼此關(guān)系的理由。逐漸,一切開始進(jìn)入正題??蛻糸_始絮絮叨叨的描述自己的需求,而我們則在緊張的做著記錄,時(shí)不時(shí)問一些問題,表明我們的立場(chǎng),抒發(fā)我們的建議。在這樣一個(gè)過程中,客戶會(huì)描述他們的每一個(gè)業(yè)務(wù),會(huì)講解每個(gè)業(yè)務(wù)的流程,他們會(huì)講出一些業(yè)務(wù)領(lǐng)域的專業(yè)詞匯(盡管有些你當(dāng)時(shí)還不太懂)。在這樣一個(gè)過程中,作為需求分析員,你應(yīng)當(dāng)非常注意業(yè)務(wù)流程中的一些關(guān)鍵詞匯,你應(yīng)當(dāng)(在當(dāng)時(shí)或者過后)將它們提取出來,通過詢問客戶,弄清楚他們的定義,以及相互之間的關(guān)系。而這些詞匯就是建立領(lǐng)域模型的開始。

這樣的討論會(huì)不可能是一次兩次,而是數(shù)次。在這樣的討論會(huì)中,也許一支筆和一摞白紙會(huì)非常有用。在這樣的討論會(huì)中,你可以迅速將從客戶那里理解的各種概念和知識(shí),立即在白紙上畫出一個(gè)又一個(gè)的草圖。那些關(guān)鍵詞匯被繪制成了一個(gè)個(gè)的概念類和它的屬性(如果確實(shí)需要),用線條迅速標(biāo)注出相互之間的關(guān)系。在你繪制的時(shí)候,客戶會(huì)在不斷地給你指正,或者說出了更多的業(yè)務(wù)知識(shí)。一張張的草圖成為了你與客戶交流的工具,也是最初始的領(lǐng)域模型。

這是一個(gè)財(cái)務(wù)軟件的業(yè)務(wù)討論會(huì),一個(gè)業(yè)務(wù)人員正在跟我講付款單是怎樣制作成憑證的。 每張付款單都有一個(gè)商品明細(xì),每個(gè)商品明細(xì)都有它的價(jià)格、數(shù)量和金額。 他指著一張付款單向我解釋著。從這句話,我可以提出一些關(guān)鍵信息:付款單、商品明細(xì)、價(jià)格、數(shù)量和金額。付款單與商品明細(xì)是一對(duì)多關(guān)系,并且商品明細(xì)聚合在付款單中。每個(gè)商品明細(xì)都有價(jià)格、數(shù)量和金額,也就是說,價(jià)格、數(shù)量和金額是商品明細(xì)的屬性,這都很清楚。緊接著,他下面的講解就不是那么清楚容易了。 如果按照一張單據(jù)生成一張憑證,那么每張付款單生成一張憑證。單據(jù)中的每個(gè)明細(xì)在憑證中生成一條借方分錄和一條貸方分錄。將付款單中的付款科目作為借方科目,將付款單結(jié)算方式對(duì)應(yīng)的結(jié)算方式科目作為貸方科目。現(xiàn)結(jié)的付款單在采購發(fā) 票中已制作憑證了,因此不再單獨(dú)制作憑證。非預(yù)付的付款單不制作憑證,而是其執(zhí)行付款核銷以后,在核銷單中制作憑證。 經(jīng)過對(duì)以上語言的分析,我們可以繪制以下關(guān)系:一張憑證包含多個(gè)分錄,是內(nèi)聚關(guān)系。分錄分為借方分錄和貸方分錄兩種。一條商品明細(xì)對(duì)應(yīng)一條借方分錄和一條貸方分錄。借方分錄中包含“借方科目”屬性,對(duì)應(yīng)付款單中的付款科目;貸方分錄中包含“貸方科目”屬性,對(duì)應(yīng)的是付款單中的一個(gè)什么科目。在這里,你可能對(duì)客戶的某些描述不明白,因此要他做出解釋。原來客戶預(yù)先制訂了一個(gè)規(guī)則,付款單中的結(jié)算方式分布對(duì)應(yīng)了一個(gè)結(jié)算方式科目。 OK ,你在繪制的圖形中,把結(jié)算方式科目作為關(guān)聯(lián)類,將結(jié)算方式和貸方科目進(jìn)行了一個(gè)關(guān)聯(lián)。這樣, 付款單生成憑證 這樣一個(gè)場(chǎng)景的領(lǐng)域模型就繪制出來。

?

2 )歸納和整理領(lǐng)域模型

在現(xiàn)場(chǎng)討論會(huì)中,可能一些關(guān)鍵的概念被你忽略掉了。也可能一些關(guān)鍵性的關(guān)系被你忽略,或者在草圖上并沒有很好地表達(dá),甚至存在謬誤和矛盾。隨著你事后的分析和整理,你從用例模型的流程描述中提取出了更多的概念。同時(shí),隨著你對(duì)問題的一步一步深入理解,你開始重構(gòu)你起初的領(lǐng)域模型。在 Evans 的《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》中,他用大量的篇幅和實(shí)例描述和講解了這樣一個(gè)過程。另外一個(gè)重要的概念是,深入理解和重構(gòu)領(lǐng)域模型不僅僅是在軟件需求分析的階段完成,它貫穿了整個(gè)軟件開發(fā)的周期。按照迭代軟件開發(fā)的思想,我們絕不能企圖在需求分析階段完成所有的分析(那是瀑布的思想)。隨著我們對(duì)業(yè)務(wù)領(lǐng)域的深入理解,重構(gòu)和精化領(lǐng)域模型貫穿整個(gè)“開發(fā)—維護(hù)—再開發(fā)”的過程中。而這也正符合了現(xiàn)代軟件開發(fā)業(yè)的發(fā)展需求(我參與的項(xiàng)目已經(jīng)經(jīng)歷了快 5 個(gè)年頭,每年都在經(jīng)歷著新的開發(fā))。

經(jīng)過了這樣的、有領(lǐng)域?qū)<覅⑴c的、反復(fù)討論與整理的過程,我們對(duì)業(yè)務(wù)領(lǐng)域理解將越來越深入,而我們?cè)O(shè)計(jì)的領(lǐng)域模型將越來越貼近現(xiàn)實(shí)世界中事物的本質(zhì)。運(yùn)用這樣的領(lǐng)域模型圖紙去開發(fā)我們的軟件,毫無疑問我們已經(jīng)成功了一半。(制作領(lǐng)域模型的更多細(xì)節(jié)見我的相關(guān)博客,我也會(huì)寫更多的文章討論)

運(yùn)用領(lǐng)域模型開發(fā)軟件

曾經(jīng)有個(gè)笑話是這樣說的:大師們站的高度都是非常高的,高到什么程度?他們都是生活在太空中的。追隨大師是一個(gè)高風(fēng)險(xiǎn)的職業(yè),為什么?一不小心就能讓我們因缺氧而死掉。這個(gè)笑話非常深刻的道出了追隨大師的關(guān)鍵,那就是怎樣“著陸”,也就是如何“落地”。一個(gè)高深的理論,如果不能指導(dǎo)我們的實(shí)際工作,那么這個(gè)理論是沒有價(jià)值的,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)也是一樣。下面我們來討論一下如何運(yùn)用領(lǐng)域模型指導(dǎo)我們的軟件開發(fā)。

1 )領(lǐng)域模型在我們的軟件框架中扮演的是什么角色

首先第一個(gè)要解決的問題是,領(lǐng)域模型在我們的軟件框架中,特別是時(shí)下最常見的 Spring+Hibernate 框架中扮演的是什么角色。我們不妨先看看 Evans 是怎樣分層的。在書中, Evans 將系統(tǒng)分為用戶界面層(表示層)、應(yīng)用層、領(lǐng)域?qū)樱P蛯樱┖突A(chǔ)結(jié)構(gòu)層。從他對(duì)各個(gè)層的表述我們不難看出,用戶界面層(表示層)就是前端界面,應(yīng)用層即是 Service 層,基礎(chǔ)結(jié)構(gòu)層即是 DAO 、工具類,以及其它的技術(shù)支持類。從這個(gè)角度來說, Evans 在他的書中所說的領(lǐng)域?qū)?,在我們的框架中就?yīng)當(dāng)是業(yè)務(wù)邏輯層( BUS ),但事實(shí)并不是這樣簡(jiǎn)單。在我們現(xiàn)在的框架中,數(shù)據(jù)與業(yè)務(wù)邏輯處理被分離了,舉例說吧:

在一個(gè)員工信息管理系統(tǒng)中,領(lǐng)域模型可能包含了一個(gè)員工類,并且在該類中包含了那些諸如員工編號(hào)、姓名、性別、職務(wù)等屬性。除此以外,一個(gè)員工類肯定也包含了諸如“新增員工”、“修改員工資料”之類的行為。領(lǐng)域模型如此,那么軟件設(shè)計(jì)時(shí)會(huì)是怎樣呢?

?

?


一堂如何提高代碼質(zhì)量的培訓(xùn)課 之 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)
??

在設(shè)計(jì)一個(gè)員工信息管理系統(tǒng)時(shí),它必然包含一個(gè)“員工 BUS ”的類,用于執(zhí)行諸如“新增員工”、“修改員工資料”之類的行為。那么,那些員工的相關(guān)屬性被放在哪里呢?它們并沒有放在“員工 BUS ”類中,而是“員工”值對(duì)象中(注意:這里的值對(duì)象不是 DDD 中的那個(gè)值對(duì)象,而是 ORM ,或者說 hibernate 中的那個(gè)值對(duì)象)。領(lǐng)域模型的員工類,在軟件系統(tǒng)中被分離為了“員工 BUS ”類和“員工”值對(duì)象類。

正是因?yàn)檫@種數(shù)據(jù)與業(yè)務(wù)邏輯處理的分離,令一些人產(chǎn)生了誤解,錯(cuò)將領(lǐng)域類對(duì)應(yīng)成了 Hibernate 對(duì)象(希望他正在看這里)。沒錯(cuò),領(lǐng)域模型對(duì)應(yīng)的是 BUS 層,但部分內(nèi)容被分離到了值對(duì)象中。

記得數(shù)年前還有 PO VO 的爭(zhēng)論,但現(xiàn)在再也沒有了。按照現(xiàn)在軟件設(shè)計(jì)的思想,從 UI 一直到數(shù)據(jù)庫,數(shù)據(jù)格式變得合成一體了。什么意思呢?頁面上的表單是什么樣子,提交到后臺(tái)的值對(duì)象就是什么樣子,最后持久化成數(shù)據(jù)庫表就是什么樣子。按照這樣的設(shè)計(jì)思想,頁面上表單中的控件 ID 、值對(duì)象中的屬性、數(shù)據(jù)庫表中的字段,都命名成了一致的名稱。這樣的設(shè)計(jì)大大簡(jiǎn)化了程序代碼,但因?yàn)楸韱闻c值對(duì)象長得一個(gè)模樣,也使得一些人誤以為領(lǐng)域類對(duì)應(yīng)的是 UI 。

2 )運(yùn)用領(lǐng)域模型開發(fā)的軟件系統(tǒng)應(yīng)當(dāng)是這樣的

不論怎樣,我認(rèn)為,運(yùn)用領(lǐng)域模型開發(fā)軟件,應(yīng)當(dāng)是以領(lǐng)域模型為中心,即以領(lǐng)域模型為藍(lán)本進(jìn)行開發(fā),就如同建筑圖紙與蓋樓一樣。領(lǐng)域模型中的某個(gè)概念類,在軟件設(shè)計(jì)時(shí)應(yīng)當(dāng)映射成對(duì)應(yīng)的 BUS 和值對(duì)象。同時(shí),為了讓開發(fā)人員更加專注地去思考那些領(lǐng)域問題,而不為其它技術(shù)細(xì)節(jié)所分析,也許以下方式不失為一個(gè)最佳實(shí)踐之一:

a. ?????? 領(lǐng)域模型被映射到了軟件框架的 BUS 層中。領(lǐng)域模型中的每個(gè)概念類,在 BUS 層中都有對(duì)應(yīng)的 XxxBus ,并且包含了這個(gè)概念類中的所有行為(函數(shù))。

b. ?????? 領(lǐng)域模型中的每個(gè)概念類都映射成了軟件系統(tǒng)中的一個(gè)值對(duì)象。這個(gè)值對(duì)象包含了概念類的所有數(shù)據(jù)(即那些屬性),以及各概念類之間的關(guān)系。但是一個(gè)值對(duì)象不一定完全對(duì)應(yīng)一個(gè)數(shù)據(jù)庫中的表(比如具有繼承關(guān)系的值對(duì)象)。特別注意,《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》中提到的值對(duì)象與 ORM 中的值對(duì)象并不是一個(gè)概念,書中的實(shí)體也與這里的實(shí)體不完全是一個(gè)概念。

c. ?????? 軟件系統(tǒng)中的 UI 盡量與值對(duì)象保持一致,即,頁面上表單中的控件 ID 盡量與值對(duì)象中的屬性保持對(duì)應(yīng),并通過諸如 DWR 的技術(shù),將 UI BUS 能夠直接交互,簡(jiǎn)化過去繁雜的 service 層操作。

d. ?????? 使用 BasicDao 這樣的通用代碼來處理數(shù)據(jù)庫持久化操作,將值對(duì)象直接扔給 insert() 、 update() 、 delete() load() 函數(shù),摒棄了過去為每個(gè)業(yè)務(wù)設(shè)計(jì) DAO 的設(shè)計(jì);采用 hql 配置文件的方式,將系統(tǒng)需要查詢的語句全部放在配置文件中,然后使用統(tǒng)一的 find() 函數(shù)執(zhí)行查詢,滿足各種各樣的查詢要求。

采用這樣一個(gè)設(shè)計(jì)框架好處多多。首先它大大簡(jiǎn)化了軟件開發(fā)的內(nèi)容,過去繁雜的 service 層和 DAO 層統(tǒng)統(tǒng)被砍掉,僅僅保留下 BUS 層和 UI 層(當(dāng)然必須有諸如 DWR 的強(qiáng)大框架和諸如 BasicDao 自開發(fā)的超輕量平臺(tái)的支持)。我始終認(rèn)為,每增加一段代碼,就增加了一份程序出錯(cuò)的機(jī)會(huì)。因此我總是不遺余力地試圖簡(jiǎn)化代碼,甚至到了發(fā)指的地步。

其次,系統(tǒng)的層次劃分會(huì)非常清晰。 UI 層就是前端的一堆 jsp 、 html js , BUS 就是一堆業(yè)務(wù)邏輯操作程序(不包含任何諸如 hql 的數(shù)據(jù)持久化代碼), hql 配置文件可以支持多配置文件,因此被分為了“員工管理”配置文件、“部門管理”配置文件、“薪金管理”配置文件。。。。。。

此外,我不得不說,世界終于變得清靜了。因?yàn)檫@樣一個(gè)框架,程序員從那么多羈絆中解脫出來了,他們終于可以全心全意地、以領(lǐng)域模型為中心、仔仔細(xì)細(xì)地開始考慮那些領(lǐng)域問題了。

在這樣一個(gè)框架中,每個(gè) BUS 都有它們自己的職責(zé),這種職責(zé)被清清楚楚地標(biāo)注在各自的注釋中。從此,系統(tǒng)開始以職責(zé)為中心設(shè)計(jì)系統(tǒng)了。

?

3 )運(yùn)用領(lǐng)域模型開發(fā)的一個(gè)簡(jiǎn)短實(shí)例

也許一個(gè)實(shí)例是最說明問題的,讓我們來舉一個(gè)項(xiàng)目評(píng)審系統(tǒng)的例子吧。

在進(jìn)行一次評(píng)審前首先要制定一個(gè)評(píng)審計(jì)劃。在這份計(jì)劃中,要詳細(xì)定義此次評(píng)審的評(píng)審人、評(píng)審材料。顯然,在領(lǐng)域模型中,評(píng)審計(jì)劃是一個(gè)重要的概念,而評(píng)審人與評(píng)審材料是聚合在評(píng)審計(jì)劃下的。隨后是在評(píng)審過程中制作評(píng)審表。每個(gè)評(píng)審人都要對(duì)評(píng)審材料制作評(píng)審表。最后,評(píng)審組織者根據(jù)評(píng)審人的意見制作評(píng)審報(bào)告。

在這樣一個(gè)需求下,我們應(yīng)當(dāng)怎樣設(shè)計(jì)“制作評(píng)審表”的業(yè)務(wù)呢?在領(lǐng)域模型中,“制作評(píng)審表”應(yīng)當(dāng)是“評(píng)審表”的職責(zé),也就是它所擁有的行為。因此,我們創(chuàng)建一個(gè)“評(píng)審表 BUS ”,并包含“制作評(píng)審表”的函數(shù)。隨后,我們開始編寫“制作評(píng)審表”的代碼。在這里,我們首先要獲取“評(píng)審者”和“評(píng)審材料”。由于這兩部分是聚會(huì)在評(píng)審計(jì)劃下的,毫無疑問我們應(yīng)當(dāng)調(diào)用“評(píng)審計(jì)劃”獲取“評(píng)審者”和“評(píng)審材料”(這里的“評(píng)審計(jì)劃”即可以設(shè)計(jì)成“評(píng)審計(jì)劃 BUS ”,也可以設(shè)計(jì)成“評(píng)審計(jì)劃”配置文件)。然后,我們通過前端與用戶交互,最終從前端獲得用戶填寫的評(píng)審表,利用 dwr 直接形成“評(píng)審表”值對(duì)象,在“保存評(píng)審表”中調(diào)用通用 DAO ,持久化“評(píng)審表”。

在這樣的設(shè)計(jì)過程中,首先當(dāng)然是設(shè)計(jì)領(lǐng)域模型了。在完成了領(lǐng)域模型的設(shè)計(jì)以后,應(yīng)當(dāng)是按照領(lǐng)域模型設(shè)計(jì) BUS 和生成值對(duì)象(實(shí)際工作中可以先生成數(shù)據(jù)庫再生成值對(duì)象)。隨后開始編寫 BUS 中的各個(gè)方法。在編寫過程中,應(yīng)當(dāng)將某個(gè)方法合理地進(jìn)行分解,根據(jù)職責(zé)去調(diào)用其它類中的方法(正如評(píng)審表去調(diào)用評(píng)審計(jì)劃獲取評(píng)審人和評(píng)審材料一樣)。通過這樣,功能被合理地分配到 BUS 的各個(gè)類中,保證了功能組織的高度內(nèi)聚。

另一個(gè)開發(fā)中可能出現(xiàn)的問題這里不得不提。按照理想的領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的流程,首先應(yīng)當(dāng)是需求分析人員分析和設(shè)計(jì)出領(lǐng)域模型,然后由開發(fā)人員照著領(lǐng)域模型設(shè)計(jì)開發(fā)。但是,由于各種各樣的原因,實(shí)際情況可能并不總是這樣。很多時(shí)候,開發(fā)人員可能沒有得到領(lǐng)域模型而僅僅只有需求文檔。這樣的情況并不意味著開發(fā)人員可以摒棄領(lǐng)域模型而直接開始編碼。在編碼前,一個(gè)簡(jiǎn)短的領(lǐng)域模型分析和繪制領(lǐng)域草圖,就是如同砍柴前的磨刀,是一個(gè)必不可少的步驟(這也是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)與以往開發(fā)模式重要的不同點(diǎn)之一)。

領(lǐng)域模型維護(hù)與二次開發(fā)

前面,我分別講述了分析人員運(yùn)用領(lǐng)域模型分析和開發(fā)人員運(yùn)用領(lǐng)域模型設(shè)計(jì)。在這兩部分,我不斷強(qiáng)調(diào)運(yùn)用草圖快速進(jìn)行領(lǐng)域模型分析。開發(fā)過程總是忙碌而緊湊的,運(yùn)用草圖快速進(jìn)行領(lǐng)域模型分析可以大大簡(jiǎn)化我們分析的過程,提高設(shè)計(jì)開發(fā)的效率。但是,這并不意味著我們可以隨意處理這些分析草圖。正如建筑設(shè)計(jì)圖是建筑設(shè)施運(yùn)行維護(hù)的重要資料,領(lǐng)域模型以及其它資料也是軟件系統(tǒng)運(yùn)行維護(hù)的重要資料。因此,我認(rèn)為,這些分析設(shè)計(jì)草圖應(yīng)當(dāng)妥善保管,并且在設(shè)計(jì)開發(fā)完成以后,應(yīng)當(dāng)專門進(jìn)行歸納整理,為今后的運(yùn)行維護(hù)和二次開發(fā)提供幫助。

另外,前面我提到, Evans 的領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),一個(gè)非常重要的思想就是持續(xù)地精化。 Evans 認(rèn)為,我們對(duì)業(yè)務(wù)領(lǐng)域的認(rèn)識(shí)是一個(gè)逐漸深刻的過程。隨著認(rèn)識(shí)的逐漸深刻,我們應(yīng)該在一些合適的時(shí)機(jī)去重構(gòu)我們的設(shè)計(jì),甚至軟件系統(tǒng)已經(jīng)設(shè)計(jì)完成并交付使用以后。這當(dāng)然要求我們拿出我們的勇氣與魄力。在完成一次重構(gòu)以后,相應(yīng)的設(shè)計(jì)文檔也應(yīng)當(dāng)同步更新。

當(dāng)我們完成了以上這些領(lǐng)域模型的維護(hù)工作,一旦有新的開發(fā)工作,有新人參與項(xiàng)目的時(shí)候,快速熟悉系統(tǒng)并適應(yīng)工作就應(yīng)當(dāng)是順理成章的事情了。而我在《軟件開發(fā)的輪回》中提到的那些痛苦的經(jīng)歷就將不再會(huì)出現(xiàn)。

?

也許以上的描述還不夠直觀,表述得還不夠清晰。后面我會(huì)通過一個(gè)實(shí)例詳細(xì)闡釋這樣的一個(gè)開發(fā)過程。

一堂如何提高代碼質(zhì)量的培訓(xùn)課 之 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 安陆市| 从化市| 德格县| 揭东县| 迁西县| 鹤岗市| 元氏县| 昌黎县| 岳阳市| 德安县| 南平市| 中超| 青龙| 利川市| 新平| 巴中市| 平顺县| 岑巩县| 太仆寺旗| 镇原县| 新余市| 商水县| 敦煌市| 大同市| 北安市| 龙游县| 汝南县| 灵璧县| 石首市| 祁门县| 临泉县| 阿拉善右旗| 莆田市| 宝清县| 和田市| 彭州市| 泰和县| 伽师县| 鄱阳县| 左云县| 新乡县|