領(lǐng)域驅(qū)動設(shè)計與模型驅(qū)動開發(fā)
《領(lǐng)域驅(qū)動設(shè)計與模型驅(qū)動開發(fā)》由會員分享,可在線閱讀,更多相關(guān)《領(lǐng)域驅(qū)動設(shè)計與模型驅(qū)動開發(fā)(142頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、領(lǐng) 域 驅(qū) 動 設(shè) 計與 模 型 驅(qū) 動 開 發(fā) 鐘 瑋 軍2015年 3月 致 謝 : 此 培 訓 材 料 借 鑒 了 來 自 參 考 文 獻 以 及 互 聯(lián) 網(wǎng) 的 大 量 資 料 , 部 分 資 料 的 參考 來 源 未 能 盡 數(shù) 列 舉 , 謹 在 此 對 那 些 在 網(wǎng) 絡(luò) 中 無 私 分 享 自 己 知 識 的 人 表 達 我的 衷 心 感 謝 ! 培訓內(nèi)容領(lǐng) 域 驅(qū) 動 設(shè) 計 簡 介領(lǐng) 域 通 用 語 言領(lǐng) 域 驅(qū) 動 設(shè) 計 的 構(gòu) 造 塊領(lǐng) 域 驅(qū) 動 設(shè) 計 編 程 實 踐CQRS架 構(gòu)模 型 驅(qū) 動 開 發(fā) 領(lǐng)域驅(qū)動設(shè)計思想的發(fā)展 2002年Martin Fower在
2、其出版企業(yè)應(yīng)用架構(gòu)模式中,歸納總結(jié)了40多種企業(yè)應(yīng)用架構(gòu)的設(shè)計模式。其中所提到的多種設(shè)計模式和概念,如事務(wù)腳本、活動記錄和領(lǐng)域模型等,對業(yè)界產(chǎn)生了深遠的影響。 2004年著名建模專家Eric Evans發(fā)表了他最具影響力的著名書籍:Domain-Driven Design Tackling Complexity in the Heart of Software(中文譯名:領(lǐng)域驅(qū)動設(shè)計軟件核心復(fù)雜性應(yīng)對之道),書中提出了“領(lǐng)域驅(qū)動設(shè)計(簡稱DDD)”的概念。 2010年Greg Young在“CQRS, Task Based UIs, Event Sourcing agh! ”一文中對Betra
3、nd Meyer的CQS模式進行改造,提出CQRS模式。 此后Jimmy Nilsson的Applying Domain-Driven Design and Patterns、Abel Avram和Floyd Marinescu合作的Domain-Driven Design Quickly、Dan Haywood的Domain-Driven Design Using Naked Objects、以及Vaughn Vernon的Implementing Domain-Driven Design等書籍的出版,豐富了領(lǐng)域驅(qū)動設(shè)計的實踐和指導。 領(lǐng)域驅(qū)動設(shè)計是什么 領(lǐng)域驅(qū)動設(shè)計事實上針對是OOAD的一
4、個擴展和延伸,DDD基于面向?qū)ο蠓治雠c設(shè)計技術(shù),對技術(shù)框架進行了分層規(guī)劃,同時對每個類進行了策略和類型的劃分。n Its a set of proven modeling techniques especially targeted to complex applications.n Its a set of principles and practices supporting the development process.n Its a set of patterns that support a clean and coherent view of the domain model.
5、n Its a set of pragmatic strategies allowing applications to scale in size and complexity maintaining their integrity. 領(lǐng)域驅(qū)動設(shè)計的特性 成 熟 、 清 晰 的 分 層 架 構(gòu) 領(lǐng) 域 對 象 與 現(xiàn) 實 世 界 的 業(yè) 務(wù) 映 射 明 確 的 職 責 劃 分分 層 架 構(gòu) 領(lǐng) 域 對 象 是 核 心 領(lǐng) 域 對 象 復(fù) 用 : 完 整 的 業(yè) 務(wù) 對 象 描 述 設(shè) 計 復(fù) 用 : 設(shè) 計 基 于 領(lǐng) 域 對 象 而 非 數(shù) 據(jù) 庫復(fù) 用 具 備 復(fù) 雜 業(yè) 務(wù) 邏 輯 的
6、 軟 件 開 發(fā) 對 設(shè) 計 和 開 發(fā) 人 員 要 求 較 高 不 適 用 普 通 CRUD的 業(yè) 務(wù) 軟 件 的 維 護 性 和 擴 展 性 良 好 (Testable)使 用 場 景 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃(一) 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃 用 戶 界 面 /展 現(xiàn) 層 負 責 向 用 戶 展 現(xiàn) 信 息 以 及 解 釋 用 戶 命 令 。展 示 層 的 組 件 實 現(xiàn) 用 戶 與 應(yīng) 用 交 互 的 功 能 。一 般 建 議 用 MVC, MVP或 者 MVVM模 式來 分 隔 這 些 組 件 為 子 層應(yīng) 用 層 很 薄 的 一 層 , 用 來 協(xié) 調(diào) 應(yīng) 用 的 活 動 , 實 現(xiàn)協(xié) 調(diào)
7、應(yīng) 用 的 “ 通 道 ” , 例 如 事 務(wù) 、 執(zhí) 行 單位 操 作 、 調(diào) 用 應(yīng) 用 程 序 的 任 務(wù) 。 它 不 包 含業(yè) 務(wù) 邏 輯 。 它 不 保 留 業(yè) 務(wù) 對 象 的 狀 態(tài) , 但它 保 有 應(yīng) 用 任 務(wù) 的 進 度 狀 態(tài) 。類 似 于 Faade模 式 , 調(diào) 用 領(lǐng) 域 層 和 基 礎(chǔ) 設(shè) 施 層 來 完 成 應(yīng) 用 的 用 例 。領(lǐng) 域 層 本 層 包 含 關(guān) 于 領(lǐng) 域 的 信 息 。 這 是 業(yè) 務(wù) 軟 件的 核 心 所 在 。 在 這 里 保 留 業(yè) 務(wù) 對 象 的 狀 態(tài) ,對 業(yè) 務(wù) 對 象 和 它 們 狀 態(tài) 的 持 久 化 被 委 托 給了 基 礎(chǔ)
8、 設(shè) 施 層 。基 礎(chǔ) 設(shè) 施層 本 層 作 為 其 他 層 的 支 撐 庫 存 在 。 它 提 供 了層 間 的 通 信 , 實 現(xiàn) 對 業(yè) 務(wù) 對 象 的 持 久 化 ,包 含 對 用 戶 界 面 層 的 支 撐 庫 等 作 用 。 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃(二) 領(lǐng)域驅(qū)動設(shè)計是對傳統(tǒng)N層架構(gòu)模式的繼承和發(fā)展 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃(三) 領(lǐng)域驅(qū)動設(shè)計是對傳統(tǒng)N層架構(gòu)模式的繼承和發(fā)展 Core J2EE Patterns 例 : J2EE參 考 分 層 架 構(gòu) 傳 統(tǒng) J2EE或Spring+Hibernate等 事 務(wù) 性編 程 模 型 只 關(guān) 心 數(shù) 據(jù) , 這 些數(shù) 據(jù) 對 象 除 了 簡
9、 單sette/getter方 法 外 , 沒 有 任何 業(yè) 務(wù) 方 法 , 被 比 喻 成 “ 失血 模 型 ” 。 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃(四) 分布式領(lǐng)域驅(qū)動設(shè)計 領(lǐng)域驅(qū)動設(shè)計分層規(guī)劃(五) 分布式領(lǐng)域驅(qū)動設(shè)計與DotNET技術(shù)架構(gòu)體系之間的關(guān)系映射 面向?qū)ο蠓治雠c設(shè)計技術(shù) 面向過程vs.面向?qū)ο?事 務(wù) 腳 本 模 式 把 業(yè) 務(wù) 邏 輯 組 織 成 單 個 過 程 , 在 過 程 中 直 接 調(diào) 用 數(shù) 據(jù) 庫 , 業(yè) 務(wù) 邏 輯 在 服 務(wù) (Service)層 處 理 。 事 務(wù) 腳 本 模 式 的 特 點 是 簡 單 容 易 理 解 , 面 向 過 程 設(shè) 計 。 對 于 少 量
10、 邏 輯 的 業(yè) 務(wù) 應(yīng) 用 來 說 , 事 務(wù) 腳 本模 式 簡 單 自 然 , 性 能 良 好 , 容 易 理 解 , 而 且 一 個 事 務(wù) 的 處 理 不 會 影 響 其 他 事 務(wù) 。 不 過 缺 點 也 很 明 顯 , 對 于 復(fù) 雜 的 業(yè) 務(wù) 邏 輯 處 理 力 不 從 心 , 難 以 保 持 良 好 的 設(shè) 計 , 事 務(wù) 之 間 的 冗 余代 碼 不 斷 增 多 , 通 過 復(fù) 制 粘 貼 方 式 進 行 復(fù) 用 。 可 維 護 性 和 擴 展 性 變 差 。 對類的策略和類型的劃分 對 類 進 行 StereoType(“ 構(gòu) 造 型 ” )劃 分 的 好 處 在 于 :
11、 ( 1) 指 導 設(shè) 計 ( 2) 幫 助 命 令 對 象 ( 3) 輔 助 理 解 按照策略和類型對類進行劃分 六邊形架構(gòu) 以領(lǐng)域模型為核心的六邊形架構(gòu) 領(lǐng)域驅(qū)動設(shè)計中的設(shè)計模式 有助于獲得柔性設(shè)計的設(shè)計模式 每 個 元 素 的 名 稱 都 提 供了 一 次 揭 示 設(shè) 計 意 圖 的機 會 。 站 在 客 戶 開 發(fā) 人員 的 角 度 上 來 思 考 它 。 人 們 為 了 使 所 有 類 和 操 作 都 具 有 相 似 的 規(guī) 模而 尋 找 一 種 一 致 的 力 度 。 粒 度 的 大 小 并 不 是唯 一 要 考 慮 的 問 題 , 我 們 還 要 考 慮 粒 度 在 哪種 場 合
12、 下 使 用 。隨 著 代 碼 重 構(gòu) 不 斷 適 合 新 理 解 的 概 念 或 需 求 ,概 念 輪 廓 也 就 逐 漸 形 成 了 。 搞 內(nèi) 聚 低 耦 合 原則 既 適 用 于 代 碼 , 也 適 用 于 概 念 。 領(lǐng) 域 驅(qū) 動 設(shè) 計 軟 件 核 心 復(fù) 雜 性 應(yīng) 對 之 道 第 10章 任 何 對 未 來 操 作 產(chǎn) 生 影 響 的 系 統(tǒng)狀 態(tài) 的 改 變 都 可 以 成 為 副 作 用 。把 命 令 和 查 詢 嚴 格 地 放 到 不 同 操作 中 ; 創(chuàng) 建 并 返 回 Value Object。允 許 我 們 安 全 地 對 多 個 操 作 進 行組 合 。 使 用
13、 斷 言 把 副 作 用 明確 表 示 出 來 , 使 它 們更 易 于 處 理 。尋 找 在 概 念 上 內(nèi) 聚 的模 型 , 更 易 推 出 預(yù) 期ASSERTION, 從 而加 快 學 習 過 程 并 避 免代 碼 矛 盾 。 盡 一 切 可 能 保 持 低 耦 合 。 把 所 有 無 關(guān) 概 念 提 取 到對 象 之 外 , 類 就 變 成 完 全 孤 立 的 了 , 使 得 我 們 可以 單 獨 地 研 究 和 理 解 它 。 每 個 孤 立 類 都 極 大 減 輕了 因 理 解 Module而 帶 來 的 負 擔 。操 作 閉 合 : 在 適 當 的 情 況 下 , 在定 義 操
14、作 時 讓 它 的 返 回 類 型 與 其參 數(shù) 相 同 。 閉 合 操 作 提 供 了 一 個高 層 接 口 , 同 時 又 不 會 引 入 對 其他 概 念 的 任 何 依 賴 性 。 培訓內(nèi)容領(lǐng) 域 驅(qū) 動 設(shè) 計 簡 介領(lǐng) 域 通 用 語 言領(lǐng) 域 驅(qū) 動 設(shè) 計 的 構(gòu) 造 塊領(lǐng) 域 驅(qū) 動 設(shè) 計 編 程 實 踐CQRS架 構(gòu)模 型 驅(qū) 動 開 發(fā) 使用通用語言的重要性 Talking different languages makes projects fail.n Programmers speak using technical jargon (design patterns
15、, acronyms, geeky in-jokes)n Domain experts use terminology specific to their field of expertise n Computers speak programming languagesn 大 家 必 須 妥 協(xié) 領(lǐng)域驅(qū)動設(shè)計的關(guān)鍵點 關(guān)注核心領(lǐng)域(Core Domain) 領(lǐng)域?qū)<液蛙浖臉I(yè)者共同開發(fā)模型 在一個明確的限界上下文(Bounded Context)中使用領(lǐng)域通用語言(ubiquitous language) 通用語言(一) 通用語言(UBIQUITOUS LANGUAGE)是團隊共享的語言。領(lǐng)
16、域?qū)<液烷_發(fā)者使用相同的通用語言進行交流。事實上,團隊中每個人都使用相同的通用語言。不管你在團隊中的角色如何,只要你是團隊的一員,你都將使用通用語言。n 通用語言是團隊自己創(chuàng)建的公用語言。團隊中同時包含領(lǐng)域?qū)<液蛙浖_發(fā)人員。n 通用語言更多地是關(guān)于業(yè)務(wù)本身如何思考和運作的,領(lǐng)域?qū)<覍νㄓ谜Z言有很大影響。不同領(lǐng)域?qū)<視诟拍詈托g(shù)語上產(chǎn)生分歧,甚至也會犯錯,當領(lǐng)域?qū)<液烷_發(fā)者一起創(chuàng)建領(lǐng)域模型的時候,他們有時會達成一致,有時會做一些妥協(xié),但最終目的都是為了創(chuàng)造最適合項目的通用語言。團隊成員們妥協(xié)的絕對不應(yīng)是通用語 言的質(zhì)量,而是概念、術(shù)語和含義。最初的一致并不表示始終一致,通用語言也會隨著時間推移
17、而不斷演化改變。n 領(lǐng)域驅(qū)動設(shè)計的一個核心思想就是使用基于模型的共同語言。因 為 模 型 是 軟 件 滿 足 領(lǐng) 域 的 共 同 點 , 它 很 適 合作 為 這 種 通 用 語 言 的 構(gòu) 造 基 礎(chǔ) 。 使 用 模 型 作 為 語 言 的 核 心 骨 架 , 要 求 團 隊 在 進 行 所 有 的 交 流 都 是 使 用 一 致 的語 言 , 在 代 碼 中 也 是 這 樣 。 在 共 享 知 識 和 推 敲 模 型 時 , 團 隊 會 使 用 語 言 、 文 字 和 圖 形 。 這 兒 需 要 確 保 團 隊 使用 的 語 言 在 所 有 的 交 流 形 式 中 看 上 去 都 是 一
18、致 的 , 這 種 語 言 被 稱 為 “ 通 用 語 言 ( Ubiquitous Language) ” 。n 通用語言的詞匯表包括類名稱和主要操作。語 言 中 包 含 術(shù) 語 , 有 些 術(shù) 語 用 來 討 論 模 型 中 已 經(jīng) 明 確 的 規(guī) 則 , 還有 一 些 術(shù) 語 則 來 自 施 加 于 模 型 上 的 高 級 組 織 原 則 。 最 后 , 團 隊 一 致 應(yīng) 用 于 領(lǐng) 域 模 型 的 模 式 名 稱 使 這 種 語 言 更為 豐 富 。 模 型 之 間 的 關(guān) 系 成 為 所 有 語 言 都 具 有 的 組 合 規(guī) 則 , 詞 和 短 語 的 意 義 反 映 了 模 型
19、 的 語 義 。 通用語言(二) 在應(yīng)用通用語言時,應(yīng)注意:n 將模型作為語言的中心。確保團隊在所有交流活動和代碼中堅持使用這種語言。在畫圖、寫東西特別是講話時也要使用這種語言。n 通過嘗試不同的表示方法(它們反映了不同模型)來消除難點。然后重構(gòu)代碼,并對類、方法和模塊重新命名,以便與新模型相一致。解決交談中的術(shù)語混淆問題,就像我們對普通詞匯形成一個公認的理解一樣。n 要認識到UBIQUITOUS LANGUAGE中的更改就是對模型的更改。n 領(lǐng)域?qū)<覒?yīng)該避免使用拗口或無法表達領(lǐng)域理解的術(shù)語或結(jié)構(gòu),開發(fā)人員應(yīng)該密切監(jiān)視那些將會妨礙設(shè)計的有歧義和不一致的地方 有了通用語言,模型就不僅僅是一個設(shè)計
20、工作了。它成為開發(fā)人員和領(lǐng)域?qū)<夜餐瓿傻拿宽椆ぷ髦械牟豢苫蛉钡牟糠?。語言以動態(tài)形式傳遞知識。使用這種語言進行討論能夠更清楚地表達圖和代碼背后的真實含義。 通用語言是那些不以代碼形式出現(xiàn)的設(shè)計方面的主要載體,這些方面包括把整個系統(tǒng)組織在一起的比例結(jié)構(gòu)、定義了不同系統(tǒng)和模型之間關(guān)系的Bounded Context,以及在模型和設(shè)計中使用的其他模式。 通用語言的應(yīng)用 通用語言貫穿于項目的各個環(huán)節(jié)n User Storiesn Project Meetingsn Team Emailsn Instant Messagesn Schedule Plann Software Documents 在限界上
21、下文中,保持語言的一致性(如口語、圖形(如UML圖等)、文字、代碼等)。 通用語言的應(yīng)用示例(一) User StoriesNOWhen User logs on with valid credentials, an empty panel is displayed.YESWhen Player logs on with valid credentials, an empty board game is displayed. (from a Tic Tac Toe Game software example) 通用語言的應(yīng)用示例(二) Code ExampleNO. Integer i = n
22、ew Integer();. String char1 = new String();. public class GameDAO() . catch (Exception e)YES . String realMeaningOfMyString = new String();. public class ScoreDataLoader() . catch (Exception NotLoggedInException) NO. Ambiguities. Inconsistencies. Synonyms. AbbreviationsYES. Clarity. Precision. Reuse
23、. Full Names package tictactoe.client.userInterface;/* Add the string O or X to a cell in the grid.*/public class ShowCellGridpublic static void displayUser (Grid grid, Cell cell) if (!Initialization.flag String mk= showString(Initialization.gameStatus .getCurrentUser().getUserString(); grid.setHTML
24、(cell.getRowIndex(), cell.getCellIndex(), mk); Initialization.gameStatus.getStatus()cell.getRowIndex()cell .getCellIndex() = Initialization.gameStatus .getCurrentUser(); GameEnd.checkEnd(Initialization.gameStatus, cell.getRowIndex(), cell.getCellIndex(); (.) A class BEFORE and AFTER Ubiquitous Langu
25、agepackage tictactoe.client.userInterface;/* Performs a move in the game.*/public class PlayerMove /* When the player clicks in a cell, the game draws an O or a X on the * game grid depending on which players turn it is.*/public static void makeMove (GameGrid gameGrid, Cell cell) if (!GameInitializa
26、tion.waitingMoveFlag String marker = showPlayerIcon(GameInitialization.currentGameStatus .getCurrentPlayer().getPlayerIcon(); gameGrid.setHTML(cell.getRowIndex(), cell.getCellIndex(), marker); GameInitialization.currentGameStatus.getGameMoves()cell.getRowIndex()cell.getCellIndex() = GameInitializati
27、on.currentGameStatus.getCurrentPlayer(); CheckWinner.checkForWinner(GameInitialization.currentGameStatus, cell.getRowIndex(), cell.getCellIndex(); (.)(Excerpted from a Tic Tac Toe Game source code) Which one would a Stakeholder better understand?Player Move Performs a move in the game. Make Move Whe
28、n the player clicks in a cell, the game draws an O or a X on the game grid depending on which players turn it is. Is Cell Empty The Player can select a cell only if it wasnt already selected.Show Cell Grid Add the String O or X to a cell in the grid. Display User Is Empty (Excerpted from a Tic Tac T
29、oe Game source code) 模型的統(tǒng)一 模型的內(nèi)部一致性又叫做“統(tǒng)一”,這樣每個術(shù)語都不會有模棱兩可的意義,也不會有規(guī)則沖突。除非模型在邏輯上是一致的,否則它就沒有意義。 識別限界上下文中的不一致:重復(fù)的概念和假同源n 重復(fù)的概念是指兩個模型元素(以及伴隨的實現(xiàn))實際上表示同一個概念。每當這個概念的信息發(fā)生改變時,都必須要更新兩個地方。每次由于新的知識導致一個對象被修改時,也必須重新分析和修改另一個對象。如果不進行實際的重新分析,結(jié)果就會出現(xiàn)同一個概念的兩個版本,它們遵守不同的規(guī)則,甚至不同的數(shù)據(jù)。更重要的是,團隊成員必須學習同一操作的兩種方法,以及保持這兩種方法同步的各種方式。
30、 n 假同源是指使用相同術(shù)語(或已實現(xiàn)的對象)的兩個人認為他們是在談?wù)撏患虑椋珜嶋H上并不是這樣。但是,當兩個定義都與同一個領(lǐng)域方面相關(guān),而只是在概念上稍有區(qū)別時,這種沖突更難以發(fā)現(xiàn)。假同源會導致開發(fā)團隊互相干擾對方的代碼,也可能導致數(shù)據(jù)庫中含有奇怪的矛盾,還會引起團隊溝通的混淆。 注意用詞詞匯n 注意正確用詞,不要歪曲詞義n 開發(fā)人員經(jīng)常習慣于使用增/刪/改/查(CRUD)此類動詞詞匯,也許有時候它們也確實屬于通用語言,但大多數(shù)情況下,它們并不能正確反映業(yè)務(wù),用詞上混淆了業(yè)務(wù)概念。 模型的分裂 在理想的世界中,我們可以有一種把整個企業(yè)領(lǐng)域包含進來的單一模型;這個模型將是統(tǒng)一的,沒有任何相
31、互矛盾或相互重疊的術(shù)語定義;每個有關(guān)領(lǐng)域的邏輯聲明都將是一致的。但大型系統(tǒng)開發(fā)并不是這樣理想。 大型系統(tǒng)領(lǐng)域模型的完全統(tǒng)一是不可行的,也不是一種經(jīng)濟有效的做法。我們可以采用限界上下文(Bounded Context)定義每個模型的應(yīng)用范圍,采用上下文映射(Context Map)給出項目上下文以及它們之間關(guān)系的總體視圖。 n 任何一個大型項目都會存在多個模型。而當基于不同模型的代碼被組合到一起后,軟件就會出現(xiàn)bug、變得不可靠和難以理解。團隊成員之間的溝通變得混亂。人們往往弄不清楚一個模型不應(yīng)該在哪個上下文中使用。n 明確地定義模型所應(yīng)用的上下文。根據(jù)團隊的組織、軟件系統(tǒng)的各個部分的用法以及物
32、理表現(xiàn)(代碼和數(shù)據(jù)庫模式等)來設(shè)置模型的邊界。在這些邊界中嚴格保持模型的一致性,而不要受到邊界之外問題的干擾和混淆。在Context中,要保證模型在邏輯上統(tǒng)一,而不用考慮它是不是適用于邊界之外的情況。在其他Context中,會使用其他的模型,這些模型具有不同的術(shù)語、概念、規(guī)則和UBIQUITOUS LANGUAGE的技術(shù)行話。 n 定義Bounded Context:視察項目的現(xiàn)狀,而不是它的理想狀態(tài)。 領(lǐng)域、子域和限界上下文 核心域、支撐域和通用域 A Core Domain is a part of the business Domain that is of primary import
33、ance to the success of the organization. It is of utmost importance to the ongoing success of the business. If a domain models some aspect of the business that is essential, yet not Core, it is a Supporting Subdomain. if a domain captures nothing special to the business, yet is required for the over
34、all business solution, it is a Generic Subdomain. Focus on the core domain 戰(zhàn)術(shù)建模與戰(zhàn)略建模 領(lǐng)域驅(qū)動設(shè)計的綜合應(yīng)用 共享內(nèi)核(Shared Kernel) 當不同團隊開發(fā)一些緊密相關(guān)的應(yīng)用程序時,如果團隊之間不進行協(xié)調(diào),即使短時間內(nèi)能夠取得快速進展,他們開發(fā)出的產(chǎn)品也可能互相不適合,最后可能不得不在轉(zhuǎn)換層上花費大量時間,而且得到的產(chǎn)品也五花八門。n 從 領(lǐng) 域 模 型 中 選 出 兩 個 團 隊 都 同 意 共 享 的 一 個 子 集 。 當 然 , 除 了 模 型 的 這 個 子 集 以 外 , 這 還 包 括 與
35、該 模 型 部 分 相 關(guān) 的 代 碼 子 集 , 或 數(shù) 據(jù) 庫 設(shè) 計 的 子 集 。 這 部 分 明 確 共 享 的 內(nèi) 容 具 有 特 殊 的 狀 態(tài) , 而 且一 個 團 隊 在 沒 與 另 一 個 團 隊 商 量 的 情 況 下 不 應(yīng) 擅 自 更 改 它 。 n 功 能 系 統(tǒng) 要 經(jīng) 常 進 行 集 成 , 但 集 成 的 頻 率 應(yīng) 該 比 團 隊 中 Continuous Integration的 頻 率 低 一 些 。 在 進行 這 些 集 成 的 時 候 , 兩 個 團 隊 都 要 運 行 測 試 。n Shared Kernel通 常 是 Core Domain, 或
36、 是 一 組 Generic Subdomain( 通 用 子 領(lǐng) 域 ) , 也 可 能 二 者 兼有 。 企業(yè)架構(gòu)方法與領(lǐng)域驅(qū)動設(shè)計3. 架 構(gòu) 內(nèi) 容 框 架 4. 企 業(yè) 連 續(xù) 系 列1. 架 構(gòu) 開 發(fā)方 法2. 架 構(gòu) 開 發(fā) 指 引 和 技 術(shù) 5. 參 考 模 型6. 架 構(gòu) 能 力 框 架 兩者都強調(diào)Business和IT的高度統(tǒng)一,很多企業(yè)架構(gòu)方法對于領(lǐng)域驅(qū)動設(shè)計“戰(zhàn)略設(shè)計”的具體實施辦法具有詳實的指導意義。如TOGAF V9構(gòu)件: eTOM業(yè)務(wù)建模Level 0 ProcessesLevel 1 Processes Level 2 Processes業(yè) 務(wù) 流 程 解
37、耦 /分 解 eTOM業(yè)務(wù)建模BSS業(yè) 務(wù) 流 程 框 架 領(lǐng) 域 解 決 特 定 問 題 eTOM信息數(shù)據(jù)模型eTOM 0級視圖 SID 1級視圖ABE:Aggregate Business Entity,ABE是 SID中一組定義良好的實體,具有高內(nèi)聚、低耦合的特征。 共 享 內(nèi) 核 eTOM信息數(shù)據(jù)模型 參考讀物 領(lǐng)域驅(qū)動設(shè)計軟件核心復(fù)雜性應(yīng)對之道及實現(xiàn)領(lǐng)域驅(qū)動設(shè)計中的相關(guān)章節(jié) 軟件方法-業(yè)務(wù)建模和需求第三章“業(yè)務(wù)建?!敝械南嚓P(guān)內(nèi)容 參考模型范例:n TMForum的 eTOM模 型 : http:/ 培訓內(nèi)容領(lǐng) 域 驅(qū) 動 設(shè) 計 簡 介領(lǐng) 域 通 用 語 言領(lǐng) 域 驅(qū) 動 設(shè) 計 的
38、 構(gòu) 造 塊領(lǐng) 域 驅(qū) 動 設(shè) 計 編 程 實 踐CQRS架 構(gòu)模 型 驅(qū) 動 開 發(fā) 領(lǐng)域驅(qū)動設(shè)計的構(gòu)造塊 Entity(實體) 實體是一個具有唯一身份標識的對象,并且可以在相當長的一段時間內(nèi)持續(xù)地變化。我們可以對實體做多次修改,故一個實體對象可能和它先前的對象大不相同,但是由于它們擁有相同的身份標識(identity),它們依然是同一個實體。 我們通過標識對對象進行區(qū)分,而不是屬性,此時我們應(yīng)該將標識作為主要的模型定義。同時我們需要保持簡單的類定義,并且關(guān)注對象在其生命周期中的連續(xù)性和唯一標識性。 隨著對象的改變,我們可能會跟蹤這樣的改變,比如什么時候發(fā)生了改變,發(fā)生了什么改變,是誰做出的
39、改變等。我們應(yīng)該慎重對待在對象整個生命周期中所發(fā)生的合法改變。 唯一的身份標識和可變性(mutability)特征將實體對象和值對象(Value Objects)區(qū)分開來。 n 很 多 時 候 , 一 個 領(lǐng) 域 概 念 應(yīng) 該 建 模 成 值 對 象 , 而 不 是 實 體 對 象 。n 實 體 和 值 對 象 是 領(lǐng) 域 模 型 概 念 , 而 不 是 數(shù) 據(jù) 存 儲 模 型 概 念 。 Value Objects(值對象) 值對象的特征n 它 度 量 或 者 描 述 了 領(lǐng) 域 中 的 一 件 東 西 。n 它 可 以 作 為 不 變 量 。n 它 將 不 同 的 相 關(guān) 的 屬 性 組
40、 合 成 一 個 概 念 整 體 n 當 度 量 和 描 述 改 變 時 , 可 以 用 另 一 個 值 對 象 予 以 替 換n 它 可 以 和 其 他 值 對 象 進 行 相 等 性 比 較n 它 不 會 對 協(xié) 作 對 象 造 成 副 作 用 。 當我們只關(guān)心一個模型元素的屬性時,應(yīng)把它歸類為值對象。我們應(yīng)該使這個模型元素能夠表示出其屬性的意義,并為它提供相關(guān)功能。值對象應(yīng)該是不可變的。不要為它分配任何標識,而且不要把它設(shè)計成Entity那么復(fù)雜。 應(yīng)該盡量使用值對象來建模而不是實體對象,即便一個領(lǐng)域概念必須建模成實體,在設(shè)計時也應(yīng)該更偏向于將其作為值對象容器,而不是子實體容器。 實體對
41、象與值對象是領(lǐng)域概念,而不是數(shù)據(jù)存儲模型概念n 值 對 象 可 以 與 其 所 在 的 實 體 對 象 保 存 在 同 一 張 表 中 , 值 對 象 的 每 一 個 屬 性 保 存 為 一 列 ; 值 對 象 也 可 以 獨 立 于 其 所 在 的 實 體 對 象 保 存 在 另 一 張表 中 , 值 對 象 獲 得 委 派 主 鍵 , 該 主 鍵 對 客 戶 端 是 不 可 見 的 。 Entity和Value Object示例 Aggregates(聚合) 在具有復(fù)雜關(guān)聯(lián)的模型中,要想保證對象更改的一致性是很困難的。不僅互不關(guān)聯(lián)的對象需要遵守一些固定規(guī)則,而且緊密關(guān)聯(lián)的各組對象也要遵守一
42、些固定規(guī)則。然而,過于謹慎的鎖定機制又會導致多個用戶之間毫無意義地互相關(guān)繞,從而使系統(tǒng)不可用。在任何具有持久化數(shù)據(jù)存儲的系統(tǒng)中,對數(shù)據(jù)進行修改的事務(wù)必須要有一個范圍,而且要有一種保持數(shù)據(jù)一致性的方式。 聚合(Aggregate)是一組相關(guān)對象的集合,我們把它作為數(shù)據(jù)修改的單元。每個聚合都有一個根和一個邊界,邊界定義了聚合的內(nèi)部都有什么,根則是聚合中所包含的一個特定實體。在聚合中,根是唯一允許外部對象保持對它的引用的元素,而邊界內(nèi)部的對象之間則可以互相引用。除根以外的其他Entity都有本地表示,但這些標識只有在聚合內(nèi)部才需要加以區(qū)別,因為外部對象除了根Entity之外看不到其他對象。 聚合行為
43、視為是一個整體,在每個事務(wù)完成時,必須要滿足聚合內(nèi)所應(yīng)用的固定規(guī)則的要求,即保證數(shù)據(jù)變化的一致性。根實體最終檢查固定規(guī)則;刪除操作必須一次刪除聚合邊界之內(nèi)的所有對象;當提交對聚合邊界內(nèi)部的任何對象的修改時,整個聚合中的所有固定規(guī)則都必須被滿足。 原則:在一致性邊界之內(nèi)建模真正的不變條件;設(shè)計小聚合;通過唯一標識引用其他聚合;在邊界之外使用最終一致性 盡量將根實體所包含的其他聚合建模成值對象,而不是實體。 Aggregates(聚合)示例 Domain Event(領(lǐng)域事件) Domain Event(領(lǐng)域事件)n 有 時 候 應(yīng) 用 需 要 記 錄 跟 蹤 事 情 的 發(fā) 生n 領(lǐng) 域 事 件
44、 經(jīng) 常 被 建 模 為 Value Object, 但 這 些 Value Object并 不 能 被 共 享 , 因為 領(lǐng) 域 事 件 本 身 是 “ 唯 一 ” 的 。n 一 個 領(lǐng) 域 事 件 是 指 一 個 在 領(lǐng) 域 中 “ 有 意 義 ” 的 事 件 Hintsn UML四 色 原 型 中 有 一 個 相 近 概 念 , 稱 為 時 刻 -時 段 原 型 (Moment-interval), 即表 示 事 物 在 某 個 時 刻 或 某 一 段 時 間 內(nèi) 發(fā) 生 。 參考:四色原型 四色原型是誕生于90年代,現(xiàn)在被廣泛使用的一種系統(tǒng)分析方法,如Borland的Together架
45、構(gòu)師版,準確地說,是由Peter Coad 和 Mark Mayfield首先提出,然后由David North拓展。 Repositories(資源庫/倉儲) 客戶需要以一種符合實際的方式來獲取對以存在的領(lǐng)域?qū)ο蟮囊?。為每種需要全局訪問的對象類型創(chuàng)建一個對象,這個對象就相當于該類型的所有對象在內(nèi)存中的一個集合的“替身”。通過一個眾所周知的接口來提供訪問。提供添加和刪除對象的方法,用這些方法來封裝在數(shù)據(jù)存儲中實際插入或刪除數(shù)據(jù)的操作。提供根據(jù)具體標準來挑選對象的方法,并返回屬性值滿足查詢標準的對象或?qū)ο蠹希ㄋ祷氐膶ο笫峭耆珜嵗模?,從而將實際的存儲和查詢技術(shù)封裝起來。只為那些確實需要直
46、接訪問的聚合提供Repository。讓客戶始終聚焦于模型,而將所有對象的存儲和訪問操作交給Repository來完成。 Repository的接口應(yīng)當采用領(lǐng)域通用語言。作為客戶端,不應(yīng)當知道數(shù)據(jù)庫實現(xiàn)的細節(jié)。 Repository和DAO的作用類似,二者的主要區(qū)別:n DAO是 比 Repository更 低 的 一 層 , 包 含 了 如 何 從 數(shù) 據(jù) 庫 中 提 取 數(shù) 據(jù) 的 代 碼 。n Repository以 “ 領(lǐng) 域 ” 為 中 心 , 所 描 述 的 是 “ 領(lǐng) 域 語 言 ” 。 Repository把 ORM框 架 與 領(lǐng) 域 模型 隔 離 , 對 外 隱 藏 封 裝
47、了 數(shù) 據(jù) 訪 問 機 制 。 Repositories(資源庫/倉儲)示例public interface AccountRepository Account findAccount(String accountId); void addAccount(Account account);public class HibernateAccountRepository implements AccountRepository private HibernateTemplate hibernateTemplate; public HibernateAccountRepository(Hiberna
48、teTemplate template) hibernateTemplate = template; public void addAccount(Account account) hibernateTemplate.save(account); public Account findAccount(final String accountId) return (Account) DataAccessUtils.uniqueResult(hibernateTemplate. findByNamedQueryAndNamedParam( “Account.findAccountByAccount
49、Id”, “accountId”, accountId); Services(領(lǐng)域服務(wù)) 當領(lǐng)域中的某個操作過程或轉(zhuǎn)換過程不是實體或值對象的職責時,我們便應(yīng)該將該操作放在一個單獨的接口中,即領(lǐng)域服務(wù)。如果勉強地把這些重要的領(lǐng)域功能歸為Entity或ValueObject的職責,那么不是歪曲了基于模型的對象的定義,就是人為地增加了一些無意義的對象。應(yīng)確保領(lǐng)域服務(wù)和通用語言是一致的,并且保證它是無狀態(tài)的。 正確區(qū)分領(lǐng)域服務(wù)(Domain Service)和應(yīng)用服務(wù)(Application Service):n 我 們 不 應(yīng) 把 業(yè) 務(wù) 邏 輯 置 于 應(yīng) 用 服 務(wù) , 但 我 們 會 把 業(yè)
50、務(wù) 邏 輯 置 于 領(lǐng) 域 服 務(wù) 中 。 (應(yīng) 用 )服 務(wù) 要 做“ 薄 ” 。 n 領(lǐng) 域 服 務(wù) 職 責 : 跨 聚 合 實 例 業(yè) 務(wù) 邏 輯 ; 沒 辦 法 合 理 放 到 實 體 中 的 其 它 業(yè) 務(wù) 邏 輯 。n 應(yīng) 用 服 務(wù) 職 責 : 跨 限 界 上 下 文 的 業(yè) 務(wù) 邏 輯 ; DTO轉(zhuǎn) 換 ; 事 務(wù) AOP、 權(quán) 限 AOP、 日 志 AOP、 異常 AOP; 外 部 系 統(tǒng) 訪 問 ( 郵 件 、 消 息 隊 列 ) 。n 領(lǐng) 域 服 務(wù) 設(shè) 計 原 則 : 用 來 組 織 業(yè) 務(wù) 邏 輯 , 面 向 業(yè) 務(wù) 邏 輯 ; 細 粒 度 ; 內(nèi) 部 視 圖 看 系
51、 統(tǒng) ; 一 個 請求 對 應(yīng) 多 個 服 務(wù) 的 多 個 方 法 ; 服 務(wù) 之 間 會 存 在 依 賴 ;n 應(yīng) 用 服 務(wù) 設(shè) 計 原 則 : 用 來 封 裝 業(yè) 務(wù) 邏 輯 ; 面 向 用 例 ; 粗 粒 度 ; 外 部 視 圖 看 系 統(tǒng) ; 一 個 請 求 對應(yīng) 一 個 方 法 ; 服 務(wù) 之 間 互 不 依 賴 。n 應(yīng) 用 服 務(wù) 和 領(lǐng) 域 服 務(wù) 區(qū) 分 非 常 敏 感 , 有 時 候 需 要 在 快 速 性 /方 便 性 上 做 折 衷 。 Services(領(lǐng)域服務(wù))示例public interface MoneyTransferService BankingTrans
52、action transfer(String fromAccountId, String toAccountId, double amount);public class MoneyTransferServiceImpl implements MoneyTransferService private final AccountRepository accountRepository; private final BankingTransactionRepository bankingTransactionRepository; public MoneyTransferServiceImpl(A
53、ccountRepository accountRepository, BankingTransactionRepository bankingTransactionRepository) BankingTransaction transfer(String fromAccountId, String toAccountId, double amount) 應(yīng)用服務(wù)、領(lǐng)域服務(wù)和基礎(chǔ)設(shè)施服務(wù) Factories(工廠) 當創(chuàng)建一個對象或創(chuàng)建整個聚合時,如果創(chuàng)建工作很復(fù)雜,或者暴露了過多的內(nèi)部結(jié)構(gòu),則可以使用Factory進行封裝。應(yīng)該將創(chuàng)建復(fù)雜對象的實例和聚合的職責轉(zhuǎn)移到一個單獨的對象,這個對象
54、本身在領(lǐng)域模型中可能沒有職責,但它仍是領(lǐng)域設(shè)計的一部分。 不同類型的工廠模式:n 工 廠 類n 工 廠 方 法 Modules(模塊) Module為人們提供了兩種觀察模型的方式,一是可以在Module中查看細節(jié),而不會被整個模型淹沒,二是觀察Module之間的關(guān)系,而不考慮其內(nèi)部細節(jié)。 模塊之間應(yīng)該是低耦合的,而在模塊內(nèi)部則是高內(nèi)聚的。模塊并不僅僅是代碼的劃分,而且也是概念的劃分。一個人一次考慮的事情是有限的(因此才有低耦合);不連貫的思想和“一鍋粥”似的思想同樣難于理解(因此才有高內(nèi)聚)。 選擇能夠描述系統(tǒng)的Module,并使之包含一個內(nèi)聚的概念集合。這通常會實現(xiàn)Module之間的低耦合,
55、但如果效果不理想,則應(yīng)尋找一種更改模型的方式來消除概念之間的耦合,或者找到一個可作為Module基礎(chǔ)的概念,基于這個概念組織的模型可以以一種有意義的方式將元素集中到一起。找到一種低耦合的概念組織方式,從而可以相互獨立地理解和分析這些概 念。對模型進行精化,直到可以根據(jù)高層領(lǐng)域概念對模型進行劃分,同時相應(yīng)的代碼也不會產(chǎn)生耦合。 Module的名稱應(yīng)該是領(lǐng)域通用語言中的術(shù)語。模塊及其名稱應(yīng)反映出領(lǐng)域的深層知識。 培訓內(nèi)容領(lǐng) 域 驅(qū) 動 設(shè) 計 簡 介領(lǐng) 域 通 用 語 言領(lǐng) 域 驅(qū) 動 設(shè) 計 的 構(gòu) 造 塊領(lǐng) 域 驅(qū) 動 設(shè) 計 編 程 實 踐CQRS架 構(gòu)模 型 驅(qū) 動 開 發(fā) 概念辨析-VO
56、/DTO/DO/PO(一) View Object(視圖對象):視圖對象,用于展示層,其作用是把某個指定頁面(或組件)的所有數(shù)據(jù)封裝起來。 Data Transfer Object(數(shù)據(jù)傳輸對象):這個概念來源于J2EE的設(shè)計模式,原來的目的是為了EJB的分布式應(yīng)用提供粗粒度的數(shù)據(jù)實體,以減少分布式調(diào)用的次數(shù),從而提高分布式調(diào)用的性能和降低網(wǎng)絡(luò)負載,但在這里,我泛指用于展示層與服務(wù)層之間的數(shù)據(jù)傳輸對象。 Domain Object(領(lǐng)域?qū)ο螅簭默F(xiàn)實世界中抽象出來的有形或無形的業(yè)務(wù)實體、值對象或領(lǐng)域服務(wù)。 Persistent Object(持久化對象):跟持久層(通常是關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)結(jié)
57、構(gòu)形成一一對應(yīng)的映射關(guān)系,如果持久層是關(guān)系型數(shù)據(jù)庫,那么,數(shù)據(jù)表中的每個字段(或若干個)就對應(yīng)PO的一個(或若干個)屬性。 Ref: http:/ 概念辨析-VO/DTO/DO/PO(二) VO與DTO:絕大多數(shù)應(yīng)用場景下,VO與DTO的屬性值基本一致,但對于設(shè)計層面來說,概念上還是存在VO和DTO的區(qū)別,DTO代表服務(wù)層需要接收的數(shù)據(jù)和返回的數(shù)據(jù),而VO代表展示層需要顯示的數(shù)據(jù)。n 示 例 : 服 務(wù) 層 有 一 個 getUser的 方 法 返 回 一 個 系 統(tǒng) 用 戶 , 其 中 有 一 個 屬 性 是gender(性 別 ), 對 于 服 務(wù) 層 來 說 , 它 只 從 語 義 上
58、定 義 : 1-男 性 , 2-女 性 , 0-未指 定 , 而 對 于 展 示 層 來 說 , 它 可 能 需 要 用 “ 帥 哥 ” 代 表 男 性 , 用 “ 美 女 ” 代 表女 性 , 用 “ 秘 密 ” 代 表 未 指 定 。 說 到 這 里 , 可 能 你 還 會 反 駁 , 在 服 務(wù) 層 直 接 就返 回 “ 帥 哥 美 女 ” 不 就 行 了 嗎 ? 對 于 大 部 分 應(yīng) 用 來 說 , 這 不 是 問 題 , 但 設(shè) 想 一下 , 如 果 需 求 允 許 客 戶 可 以 定 制 風 格 , 而 不 同 風 格 對 于 “ 性 別 ” 的 表 現(xiàn) 方 式 不一 樣 , 又
59、 或 者 這 個 服 務(wù) 同 時 供 多 個 客 戶 端 使 用 ( 不 同 門 戶 ) , 而 不 同 的 客 戶 端對 于 表 現(xiàn) 層 的 要 求 有 所 不 同 , 那 么 , 問 題 就 來 了 。 再 者 , 回 到 設(shè) 計 層 面 上 分 析 , 從 職 責 單 一 原 則 來 看 , 服 務(wù) 層 只 負 責 業(yè) 務(wù) , 與 具 體 的 表 現(xiàn) 形 式 無 關(guān) , 因 此 , 它返 回 的 DTO, 不 應(yīng) 該 出 現(xiàn) 與 表 現(xiàn) 形 式 的 耦 合 。n 實 現(xiàn) 層 面 是 否 需 要 區(qū) 分 二 者 概 念 ? 具 體 問 題 具 體 分 析 概念辨析-VO/DTO/DO/PO
60、(三) DTO與DO:DTO是展示層和服務(wù)層之間的數(shù)據(jù)傳輸對象(可以認為是兩者之間的協(xié)議),而DO是對現(xiàn)實世界各種業(yè)務(wù)角色的抽象,這就引出了兩者在數(shù)據(jù)上的區(qū)別,例如UserInfo和User,對于一個getUser方法來說,本質(zhì)上它永遠不應(yīng)該返回用戶的密碼,因此UserInfo至少比User少一個password的數(shù)據(jù)。而在領(lǐng)域驅(qū)動設(shè)計中,DO不是簡單的POJO,它具有領(lǐng)域業(yè)務(wù)邏輯。 n 在 設(shè) 計 層 面 , 展 示 層 向 服 務(wù) 層 傳 遞 的 DTO與 服 務(wù) 層 返 回 給 展 示 層 的 DTO在 概 念 上 是 不 同 的 (如 返 回 UserInfo應(yīng) 該 不 包 含 pas
61、sword, 但 創(chuàng) 建User傳 入 的 參 數(shù) 需 要 包 含 password), 但 在 實 現(xiàn) 層 面 , 我 們 通 常 很 少 會 這 樣 做 ( 定 義 兩 個 UserInfo, 甚 至 更 多 ) , 因 為 這 樣 做 并 不 見 得 很 明智 , 我 們 完 全 可 以 設(shè) 計 一 個 完 全 兼 容 的 DTO, 在 服 務(wù) 層 接 收 數(shù) 據(jù) 的 時 候 , 不 該 由 展 示 層 設(shè) 置 的 屬 性 ( 如 訂 單 的 總 價 應(yīng) 該 由 其 單 價 、 數(shù) 量 、 折扣 等 決 定 ) , 無 論 展 示 層 是 否 設(shè) 置 , 服 務(wù) 層 都 一 概 忽 略
62、, 而 在 服 務(wù) 層 返 回 數(shù) 據(jù) 時 , 不 該 返 回 的 數(shù) 據(jù) ( 如 用 戶 密 碼 ) , 就 不 設(shè) 置 對 應(yīng) 的 屬 性 。n 為 什 么 不 在 服 務(wù) 層 中 直 接 返 回 DO: DO具 有 一 些 不 應(yīng) 該 讓 展 示 層 知 道 的 數(shù) 據(jù) ; DO具 有 業(yè) 務(wù) 方 法 , 如 果 直 接 把 DO傳 遞 給 展 示 層 , 展 示 層 的 代碼 就 可 以 繞 過 服 務(wù) 層 直 接 調(diào) 用 它 不 應(yīng) 該 訪 問 的 操 作 , 對 于 基 于 AOP攔 截 服 務(wù) 層 來 進 行 訪 問 控 制 的 機 制 來 說 , 這 問 題 尤 為 突 出 ,
63、 而 在 展 示 層 調(diào)用 DO的 業(yè) 務(wù) 方 法 也 會 因 為 事 務(wù) 的 問 題 , 讓 事 務(wù) 難 以 控 制 ; ORM框 架 ( 如 Hibernate) “ 延 遲 加 載 ” 技 術(shù) , 如 果 直 接 把 DO暴 露 給 展 示 層 , 對 于 大 部 分 情 況 , 展 示 層 不 在 事 務(wù) 范 圍 之 內(nèi) , 如 果 其 嘗 試 在 Session關(guān) 閉 的 情 況 下 獲 取 一 個 未 加 載 的 關(guān) 聯(lián) 對 象 , 會 出 現(xiàn) 運 行 時 異 常 ( 對 于Hibernate來 說 , 就 是 LazyInitiliaztionException) ; 從 設(shè) 計
64、 層 面 來 說 , 展 示 層 依 賴 于 服 務(wù) 層 , 服 務(wù) 層 依 賴 于 領(lǐng) 域 層 , 如 果 把 DO暴 露 出 去 , 就會 導 致 展 示 層 直 接 依 賴 于 領(lǐng) 域 層 , 這 雖 然 依 然 是 單 向 依 賴 , 但 這 種 跨 層 依 賴 會 導 致 不 必 要 的 耦 合 。n DTO應(yīng) 該 是 一 個 “ 扁 平 的 二 維 對 象 ” 概念辨析-VO/DTO/DO/PO(四) DO與PO:DO和PO在絕大部分情況下是一一對應(yīng)的,PO是只含有g(shù)et/set方法的POJO,但某些場景還是能反映出兩者在概念上存在本質(zhì)的區(qū)別。n DO在 某 些 場 景 下 不 需
65、 要 進 行 顯 式 的 持 久 化 , 例 如 利 用 策 略 模 式 設(shè) 計 的 商 品 折 扣 策 略 , 會 衍 生 出 折 扣 策 略 的 接 口 和 不 同 折 扣 策 略 實 現(xiàn) 類 , 這些 折 扣 策 略 實 現(xiàn) 類 可 以 算 是 DO, 但 它 們 只 駐 留 在 靜 態(tài) 內(nèi) 存 , 不 需 要 持 久 化 到 持 久 層 , 因 此 , 這 類 DO是 不 存 在 對 應(yīng) 的 PO的 。 同 樣 的 道 理 ,某 些 場 景 下 , PO也 沒 有 對 應(yīng) 的 DO, 例 如 老 師 Teacher和 學 生 Student存 在 多 對 多 的 關(guān) 系 , 在 關(guān) 系
66、 數(shù) 據(jù) 庫 中 , 這 種 關(guān) 系 需 要 表 現(xiàn) 為 一 個 中 間 表 , 也 就 對 應(yīng) 有 一 個 TeacherAndStudentPO的 PO, 但 這 個 PO在 業(yè) 務(wù) 領(lǐng) 域 沒 有 任 何 現(xiàn) 實 的 意 義 , 它 完 全 不 能 與 任 何 DO對 應(yīng) 上 。 這 里 要 特 別 聲 明 ,并 不 是 所 有 多 對 多 關(guān) 系 都 沒 有 業(yè) 務(wù) 含 義 , 這 跟 具 體 業(yè) 務(wù) 場 景 有 關(guān) , 例 如 : 兩 個 PO之 間 的 關(guān) 系 會 影 響 具 體 業(yè) 務(wù) , 并 且 這 種 關(guān) 系 存 在 多 種 類 型 ,那 么 這 種 多 對 多 關(guān) 系 也 應(yīng) 該 表 現(xiàn) 為 一 個 DO, 又 如 : “ 角 色 ” 與 “ 資 源 ” 之 間 存 在 多 對 多 關(guān) 系 , 而 這 種 關(guān) 系 很 明 顯 會 表 現(xiàn) 為 一 個 DO“權(quán)限 ” 。n 某 些 情 況 下 , 為 了 某 種 持 久 化 策 略 或 者 性 能 的 考 慮 , 一 個 PO可 能 對 應(yīng) 多 個 DO, 反 之 亦 然 。 例 如 客 戶 Customer有 其 聯(lián)
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 6.煤礦安全生產(chǎn)科普知識競賽題含答案
- 2.煤礦爆破工技能鑒定試題含答案
- 3.爆破工培訓考試試題含答案
- 2.煤礦安全監(jiān)察人員模擬考試題庫試卷含答案
- 3.金屬非金屬礦山安全管理人員(地下礦山)安全生產(chǎn)模擬考試題庫試卷含答案
- 4.煤礦特種作業(yè)人員井下電鉗工模擬考試題庫試卷含答案
- 1 煤礦安全生產(chǎn)及管理知識測試題庫及答案
- 2 各種煤礦安全考試試題含答案
- 1 煤礦安全檢查考試題
- 1 井下放炮員練習題含答案
- 2煤礦安全監(jiān)測工種技術(shù)比武題庫含解析
- 1 礦山應(yīng)急救援安全知識競賽試題
- 1 礦井泵工考試練習題含答案
- 2煤礦爆破工考試復(fù)習題含答案
- 1 各種煤礦安全考試試題含答案