中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)實(shí)踐

  領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的關(guān)注重心是領(lǐng)域,尤其在面對(duì)復(fù)雜的領(lǐng)域邏輯時(shí),它總能夠幫助我們很好地分析領(lǐng)域。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的基礎(chǔ)是領(lǐng)域建模。Eric認(rèn)為需要和領(lǐng)域?qū)<伊己玫睾献鳎瑥慕徽勚邪l(fā)現(xiàn)通用語言,找到領(lǐng)域的關(guān)鍵詞。領(lǐng)域建模是迭代的過程,根據(jù)逐漸深入的領(lǐng)域知識(shí)來精化模型。不過,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)并不排斥其他的分析技術(shù),例如分析模式,或者通過測(cè)試驅(qū)動(dòng)開發(fā)來引導(dǎo)我們找到問題域的領(lǐng)域模型。

  領(lǐng)域建模并非領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)所獨(dú)有。在RUP中,領(lǐng)域建模就是一個(gè)非常重要的環(huán)節(jié)。它是一種用例驅(qū)動(dòng)的開發(fā)方法,通過獲得的用例來幫助分析和設(shè)計(jì)人員尋找對(duì)象,以及對(duì)象之間的關(guān)系。根據(jù)我個(gè)人的經(jīng)驗(yàn),我喜歡采用兩種截然不同的方式來獲得模型。一種是用例驅(qū)動(dòng),一種則是測(cè)試驅(qū)動(dòng)。在得到初步的領(lǐng)域模型中,我會(huì)嘗試?yán)妙I(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的思想為對(duì)象分類,找到實(shí)體、值對(duì)象、聚合以及服務(wù)對(duì)象,并通過分析對(duì)象的生命周期,為不同類型的對(duì)象建立資源庫(kù)和工廠對(duì)象。

  本文將以一個(gè)讀者耳熟能詳?shù)膱D書館管理系統(tǒng)作為我們要分析的領(lǐng)域,嘗試講解如何在項(xiàng)目開發(fā)中應(yīng)用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)。我將選擇用例驅(qū)動(dòng)的方式來獲得我最初的領(lǐng)域模型。簡(jiǎn)單起見,我先給出分析領(lǐng)域的用例以及用例圖。

  借書:讀者攜帶要借書籍到借書處。圖書館工作人員首先掃描讀者的借書卡,獲得讀者信息,然后掃描書籍的條形碼。如果借閱多本,則掃描多本書籍。掃描時(shí),需要判斷當(dāng)前讀者的類型,獲得讀者可借書籍?dāng)?shù)。如果借閱書籍超出,則提示。如果掃描失敗,允許工作人員手工輸入編號(hào)。借閱的期限為1個(gè)月。

  還書:讀者攜帶要還書籍到還書處。圖書館工作人員掃描書籍的條形碼,進(jìn)行還書操作。如果借閱的書籍超期,則提示,并計(jì)算出應(yīng)收罰款的數(shù)額。如果掃描失敗,允許工作人員手工輸入編號(hào)。

  我采用了摘要方式來描述用例。我喜歡這樣一種簡(jiǎn)潔的方式,它實(shí)際上等同于XP中的用戶故事。在需求并不復(fù)雜的時(shí)候,或者在對(duì)文檔要求并不嚴(yán)格的時(shí)候,都可以采用這種方式來編寫用例。

  以下是表達(dá)上述兩個(gè)用例的用例圖展現(xiàn):

clip_image002

  可以首先利用名詞/動(dòng)詞法找到模型中的領(lǐng)域?qū)ο蟆_@種方法雖然極度地簡(jiǎn)單與低級(jí),然后在建立領(lǐng)域模型之初,是非常有效的手段。通過對(duì)用例的分析,大致可以獲得如下對(duì)象:Reader,Administrator,Book,Library Card以及Scanner。也許還有我們未曾發(fā)現(xiàn)的領(lǐng)域?qū)ο螅@可以通過深入領(lǐng)域或與客戶交談來進(jìn)一步獲得。我們可以嘗試著先獲得一個(gè)最簡(jiǎn)單的領(lǐng)域模型,如下所示。

clip_image004

  我們發(fā)現(xiàn)Administrator對(duì)象是一個(gè)孤立的對(duì)象,它與其他領(lǐng)域?qū)ο鬀]有產(chǎn)生任何關(guān)系。至少在借書、還書用例中,我們并不需要管理這個(gè)對(duì)象,可以考慮刪除它。模型中的Scanner對(duì)象非常特殊,表面上它會(huì)對(duì)Book與LibraryCard進(jìn)行操作,然而對(duì)于Scanner而言,它并不關(guān)心操作的是什么對(duì)象,而只需要掃描條形碼,返回一個(gè)字符串。這是一種行為的體現(xiàn)。在整個(gè)系統(tǒng)中,Scanner對(duì)象可以只擁有一個(gè),沒有屬性和狀態(tài),僅提供掃描功能,或者說是服務(wù),因此可以考慮將其定義為服務(wù)對(duì)象。

  Reader與Book之間的關(guān)系非常直接,可是在引入LibraryCard之后,這個(gè)關(guān)系就顯得有些尷尬了。仔細(xì)閱讀用例,我們發(fā)現(xiàn)識(shí)別讀者的信息,是通過借書卡來獲取的。無論是借書還是還書,都可以通過借書卡來獲得讀者當(dāng)前借閱的書。此時(shí),讀者與書之間就不存在任何關(guān)系了,它已經(jīng)進(jìn)行了轉(zhuǎn)嫁。既然借書卡已經(jīng)實(shí)現(xiàn)了對(duì)借書關(guān)系的管理,我們還有必要保留Reader對(duì)象嗎?閱讀用例,我們知道在掃描借書卡時(shí),會(huì)獲得讀者的信息。雖然我們可以在借書卡中保留這些信息,但根據(jù)單一職責(zé)原則(SRP),將其專門封裝為一個(gè)對(duì)象仍有必要。

  目前,借書卡僅僅維護(hù)了讀者當(dāng)前借閱的書籍,那么,還需要維護(hù)借閱和返還的歷史記錄嗎?從用例的描述來看,并沒有這一功能。我們感到疑惑,因?yàn)楸A魵v史記錄是大多數(shù)系統(tǒng)所必備的。此時(shí),客戶的答案就顯得格外重要。“哦,是的,我們需要查看歷史記錄!”這是客戶給我們的肯定答復(fù)。顯然,查看歷史記錄屬于另一個(gè)用例,它甚至可能屬于另外一個(gè)上下文(Context),例如關(guān)于“查詢”的上下文。然而,這一信息的來源卻來自于借閱與返回用例,我們應(yīng)該將其識(shí)別出來。如果其他用例需要用到,我認(rèn)為這個(gè)對(duì)象是需要共享的。細(xì)化后的領(lǐng)域模型如下:

clip_image006

  通過對(duì)掃描行為的分析,我認(rèn)為Scanner提供的掃描行為與領(lǐng)域無關(guān),而是一種基礎(chǔ)設(shè)施,因此我將其定義為基礎(chǔ)設(shè)施層的服務(wù)。模型增加了FineCalculator對(duì)象,用以完成對(duì)超期讀者的罰款金額計(jì)算。顯然,它是一個(gè)服務(wù)對(duì)象。注意,BorrowingHistory與Book是一對(duì)一的關(guān)系,因?yàn)槲覀冃枰獮槊恳槐緯⒁粭l借閱歷史記錄。

  現(xiàn)在,我們需要識(shí)別領(lǐng)域模型中的實(shí)體和值對(duì)象,以及可能的聚合。我們需要一個(gè)唯一的標(biāo)識(shí)來區(qū)別讀者,且這一標(biāo)識(shí)具有連續(xù)性,因此Reader是一個(gè)實(shí)體對(duì)象。同樣,Book對(duì)象也是一個(gè)實(shí)體對(duì)象,因?yàn)槲覀冃枰粋€(gè)唯一標(biāo)識(shí)來完成對(duì)書籍的跟蹤。注意,在這個(gè)模型中的Book實(shí)體,其實(shí)例代表的是具體的某一本書,而不是指同一種書。因?yàn)閳D書館可能就同一種書購(gòu)買多本,而讀者借閱的是真實(shí)的書本,而不僅僅是書的屬性。此時(shí),Book的標(biāo)識(shí)ID就顯得尤為重要,甚至不能用書籍的ISBN來標(biāo)識(shí)。

  從表面上看,BorrowingHistory同樣屬于實(shí)體對(duì)象,它的每一條記錄都是唯一的,即使存在兩條歷史記錄,具有相同的讀者ID與書籍ID,我們?nèi)詫⑵湟暈椴煌挠涗洠驗(yàn)樗鼈兊慕栝啎r(shí)間并不相同。不過,對(duì)于系統(tǒng)的調(diào)用者而言,通常不會(huì)去關(guān)注所有的借閱記錄,而是查詢某位讀者的借閱記錄,因此,我們可以將其作為與Reader放在一起的聚合。然而,隨著對(duì)需求的深入分析,我們發(fā)現(xiàn)定義這樣的聚合存在問題,因?yàn)槲覀兛赡苓€需要查詢某本書的借閱記錄(例如,希望知道哪本書最受歡迎,跟蹤每本書的借閱情況等)。由于Reader和Book應(yīng)該分屬于不同的聚合,BorrowingHistory就存在無法劃定聚合的問題。既然如此,我們應(yīng)該將其分離出來,作為一個(gè)單獨(dú)的聚合根。

  讓人感覺疑惑不解的是LibraryCard對(duì)象。一方面,它的ID來源于Reader,且存在一對(duì)一的關(guān)系,因此它可以作為Reader聚合的一部分。根據(jù)模型圖來看,它實(shí)際上又記錄了讀者與書之間的關(guān)系。仔細(xì)分析,LibraryCard所維護(hù)的這樣一種讀者與書的關(guān)系,事實(shí)上正是BorrowingHistory的一種體現(xiàn),區(qū)別僅在于一個(gè)記錄了當(dāng)前的借書信息,一個(gè)還包括過去的借書信息。BorrowingHistory可以進(jìn)行信息的持久化,LibraryCard則完全可以在內(nèi)存中維持一個(gè)當(dāng)前借閱信息的集合。因此,可以將LibraryCard定義在Reader聚合中。這樣既可以減少對(duì)象之間的關(guān)聯(lián),又能保證對(duì)象之間的一致性。

  我們還需要深入分析Reader對(duì)象和Book對(duì)象的標(biāo)識(shí)ID,因?yàn)檫@兩者的標(biāo)識(shí)ID都是通過基礎(chǔ)設(shè)施的Scanner服務(wù)獲得的。Scanner并沒有能力知道二者之間的區(qū)別。而在借閱書籍時(shí),根據(jù)需求規(guī)定的流程,必須是先掃描借書卡,獲得讀者信息,然后再掃描書。此外,當(dāng)掃描出現(xiàn)錯(cuò)誤時(shí),系統(tǒng)需要支持操作人員手工輸入,因此對(duì)手工輸入的內(nèi)容也需要進(jìn)行ID的驗(yàn)證。我們需要有專門驗(yàn)證ID的對(duì)象。

  我們還要考慮許多業(yè)務(wù)規(guī)則,例如是否允許讀者借書的規(guī)則,是否超期的規(guī)則,計(jì)算罰款額度的規(guī)則。如果這些規(guī)則極為簡(jiǎn)單,且不具有變化的可能,可以放在領(lǐng)域?qū)ο笾小H欢坏┮?guī)則變得復(fù)雜,就會(huì)嚴(yán)重干擾相關(guān)領(lǐng)域?qū)ο蟮穆氊?zé)。根據(jù)職責(zé)分離的原則,我們可以提供專門的規(guī)則對(duì)象,即領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中規(guī)格模式的應(yīng)用。如果可能變化,我們甚至可以引入策略模式,對(duì)這些規(guī)則進(jìn)行抽象。經(jīng)過分析后得到的領(lǐng)域模型如下所示:

clip_image008

  Reader實(shí)體對(duì)象和LibraryCard實(shí)體對(duì)象處于同一個(gè)聚合中,其中Reader為聚合根。BorrowingSpecification和ReturningSepecification均為值對(duì)象,并放在Reader聚合中。FineCalculator是一個(gè)服務(wù)對(duì)象,它會(huì)調(diào)用FineRule值對(duì)象獲得罰款規(guī)則,通過計(jì)算后返回Money值對(duì)象值。由于聚合的原因,原來FineCalculator與LibraryCard之間的關(guān)系已經(jīng)修改為計(jì)算Reader的罰款。

  BorrowingHistory和Book均為實(shí)體對(duì)象,而IdentityValidator則為服務(wù)對(duì)象,負(fù)責(zé)驗(yàn)證掃描碼。

  接下來需要為領(lǐng)域?qū)ο筮x擇資源庫(kù)(Repository)。在領(lǐng)域模型中,只有Reader、BorrowingHistory和Book三個(gè)實(shí)體為聚合根對(duì)象,因此只需要為這三個(gè)對(duì)象建立資源庫(kù)對(duì)象即可。

clip_image010

  由于需求較為簡(jiǎn)單,建立的領(lǐng)域模型已經(jīng)比較完善,我們可以著手編碼,對(duì)這些模型進(jìn)行驗(yàn)證。本文沒有考慮限定上下文的情況,我希望未來的文章能夠以真實(shí)的案例對(duì)此進(jìn)行表述。整體而言,根據(jù)這個(gè)案例,我們已經(jīng)能夠初步領(lǐng)略領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的基本步驟。

it知識(shí)庫(kù)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)實(shí)踐,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲精品久久久久久一区二区 | 精品国产欧美一区二区 | 免费在线一区二区 | 在线观看www视频 | 久草视频在 | 日韩精品一区二 | 成人一区二区三区在线 | 亚洲一区在线日韩在线深爱 | 色吧色综合| 男女免费在线观看视频 | 成人精品国产免费网站 | 久久久999国产精品 中文字幕在线精品 | 精品国产欧美一区二区三区成人 | 久久精品91 | 天天插天天操 | 亚洲国产欧美国产综合一区 | 国产欧美一区二区久久性色99 | av黄色片在线观看 | 日韩一级免费电影 | 亚洲国产黄 | 一区二区三区精品视频 | 国产精品久久久久久久久久久久午夜片 | 久久一视频 | 日韩精品一区二区三区在线观看 | 夜夜爆操 | 久久免费视频在线 | 51ⅴ精品国产91久久久久久 | 91精品国产综合久久国产大片 | 男人久久天堂 | 亚洲视频手机在线 | 在线国产一区 | 欧美不卡视频一区发布 | 国产精品久久久久久久久久免费看 | 久久精品中文字幕 | 成年人在线视频 | 午夜影院在线观看视频 | 亚洲精品国产第一综合99久久 | 中文字幕不卡 | 免费观看的黄色网址 | 国产精品视频区 | 欧美精品一区二区三区蜜臀 |