內容簡介
本書全面詳細地解釋了領域驅動設計、測試驅動開發、依賴注入、持久化、重構、模式等很多基本概念,並以C#和NET實例為依託,展示了這些概念的實際套用和重要價值。更重要的是,本書還將這些概念整合到一起,為開發人員從頭至尾地揭示了完整的開發路線。閱讀本書後,讀者將能真正掌握這些重 要概念,並有效地將它們結合起來,套用到實際開發過程中。
本書適合軟體架構師和開發人員閱讀。
作者簡介
Jimmy Nilsson,資深軟體架構師,有超過20年從業經驗,2008年在瑞典主要IT媒體評選的全國軟體架構師和開發人員排行榜上名列第2。目前擔任factor10諮詢公司CEO,客戶包括愛立信、微軟、沃爾沃等。本書是他的代表作,已被翻譯為日、俄等多種文字,他的另一部著作.NET Enterprise Design with Visual Basic .NET and SQL Server 2000也獲得非常好的評價。
編輯推薦
《領域驅動設計與模式實戰》:.NET開發人員必讀之作,帶領讀者踏上領域驅動設計世界的實用、博學之旅。
《企業套用架構模式》與《領域驅動設計》兩大名著精髓的實戰演練。
不僅足夠詳細地解釋了基本思想,而且將一系列思想綜合到一起,幫助開發
人員從頭到位了解整個路線。
教你穿越業務層、數據層和UI層之間重重障礙,打通任督二脈。
Martin Fowler和Eric Evans兩位大師聯袂推薦。
模式、領域驅動設計和測試驅動開發賦予架構師和開發人員前所未有的能力。使他們能夠創建功能強大、健壯且可維護的系統。但是,如何在實際項目中充分發揮這些利器的潛力呢?
《領域驅動設計與模式實戰》中,作者將Martin Fowler《企業套用架構模式》和Eric Evans《領域驅動設計》兩部經典名著中的思想精髓以及重構、測試驅動開發等技術融會貫通,並通過大量C#實例加以闡釋,跨越了領域模型、資料庫與UI層之間的障礙。真實展示了創建高質量的企業級套用架構的全部過程。
《領域驅動設計與模式實戰》就像是精彩紛呈的旅行見聞,每一處的所思所想都閃耀著智慧的光芒。生動詮釋了作者對面向對象開發中各種設計選擇的深刻理解。
圖書目錄
第一部分 背景知識
第1章 應重視的價值,也是對過去幾年的沉重反思
1.1 總體價值
1.2 應重視的架構風格
1.2.1 焦點之一:模型
1.2.2 焦點之二:用例
1.2.3 如果重視模型,就可以使用領域模型模式
1.2.4 慎重處理資料庫
1.2.5 領域模型與關係資料庫之間的阻抗失配
1.2.6 謹慎處理分散式
1.2.7 訊息傳遞很重要
1.3 對過程的各個組成部分的評價
1.3.1 預先架構設計
1.3.2 領域驅動設計
1.3.3 測試驅動開發
1.3.4 重構
1.3.5 選擇一種還是選擇組合
1.4 持續集成
1.4.1 解決方案(或至少是正確方向上的一大步)
1.4.2 從我的組織汲取的教訓
1.4.3 更多信息
1.5 不要忘記運行機制
1.5.1 有關何時需要運行機制的一個例子
1.5.2 運行機制的一些例子
1.5.3 它不僅僅是我們的過錯
1.6 小結
第2章 模式起步
2.1 模式概述
2.1.1 為什麼要學習模式
2.1.2 在模式方面要注意哪些事情
2.2 設計模式
2.3 架構模式
2.3.1 示例:層
2.3.2 另一個示例:領域模型模式
2.4 針對具體應用程式類型的設計模式
2.5 領域模式
2.6 小結
第3章 TDD與重構
3.1 TDD
3.1.1 TDD流程
3.1.2 演示
3.1.3 設計效果
3.1.4 問題
3.1.5 下一個階段
3.2 模擬和樁
3.2.1 典型單元測試
3.2.2 聲明獨立性
3.2.3 處理困難因素
3.2.4 用測試樁替換協作對象
3.2.5 用模擬對象替換協作對象
3.2.6 設計含義
3.2.7 結論
3.2.8 更多信息
3.3 重構
3.4 小結
第二部分 套用DDD
第4章 新的默認架構
4.1 新的默認架構的基礎知識
4.1.1 從以資料庫為中心過渡到以領域模型為中心
4.1.2 進一步關注DDD
4.1.3 根據DDD進行分層
4.2 輪廓
4.2.1 領域模型示例的問題/特性
4.2.2 逐個處理特性
4.2.3 到目前為止的領域模型
4.3 初次嘗試將UI與領域模型掛接
4.3.1 基本目標
4.3.2 簡單UI的當前焦點
4.3.3 為客戶列出訂單
4.3.4 添加訂單
4.3.5 剛才我們看到了什麼
4.4 另一個維度
4.4.1 領域模型的位置
4.4.2 孤立或共享的實例
4.4.3 有狀態或無狀態領域模型實例化
4.4.4 領域模型的完整實例化或子集實例化
4.5 小結
第5章 領域驅動設計進階
5.1 通過簡單的TDD實驗來精化領域模型
5.1.1 從Order和OrderFactory的創建開始
5.1.2 一些領域邏輯
5.1.3 第二個任務:OrderRepository+OrderNumber
5.1.4 重建持久化的實體:如何從外部設定值
5.1.5 獲取訂單列表
5.1.6 該到討論實體的時候了
5.1.7 再次回到流程上來
5.1.8 總覽圖
5.1.9 建立OrderRepository的偽實現
5.1.10 簡單討論一下保存
5.1.11 每個訂單的總量
5.1.12 歷史客戶信息
5.1.13 實例的生命周期
5.1.14 訂單類型
5.1.15 訂單的介紹人
5.2 連貫接口
5.3 小結
第6章 準備基礎架構
6.1 將POCO作為工作方式
6.1.1 實體和值對象的PI
6.1.2 是否使用PI
6.1.3 運行時與編譯時PI
6.1.4 PI實體/值對象的代價
6.1.5 將PI用於存儲庫
6.1.6 單組存儲庫的代價
6.2 對保存場景的處理
6.3 建立偽版本機制
6.3.1 偽版本機制的更多特性
6.3.2 偽版本的實現
6.3.3 影響單元測試
6.4 資料庫測試
6.4.1 在每次測試之前重置資料庫
6.4.2 在測試運行期間保持資料庫的狀態
6.4.3 測試之前重置測試所使用的數據
6.4.4 不要忘記不斷演變的模式
6.4.5 分離單元測試和資料庫調用測試
6.5 查詢
6.5.1 單組查詢對象
6.5.2 單組查詢對象的代價
6.5.3 將查詢定位到哪裡
6.5.4 再次將聚合作為工具
6.5.5 將規格用於查詢
6.5.6 其他查詢選擇
6.6 小結
第7章 套用規則
7.1 規則的分類
7.2 規則的原則及用法
7.2.1 雙向規則檢查:可選的(可能的)主動檢查,必需的(和自動的)被動檢查
7.2.2 所有狀態(即使是錯誤狀態)都應該是可保存的
7.2.3 規則應該高效使用
7.2.4 規則應該是可配置的,以便添加自定義規則
7.2.5 規則應與狀態放在一起
7.2.6 規則應該具有很高的可測試性
7.2.7 系統應阻止我們進入錯的狀態
7.3 開始創建API
7.3.1 上下文,上下文,還是上下文
7.3.2 資料庫約束
7.3.3 將規則綁定到與領域有關的轉換,還是綁定到與基礎架構有關的轉換
7.3.4 精化原則:所有狀態,即使是錯誤狀態,都應該是可保存的
7.4 與持久化有關的基本的規則API的需求
7.4.1 回到已發現的API問題上
7.4.2 問題是什麼
7.4.3 我們允許了不正確的轉換
7.4.4 如果忘記檢查怎么辦
7.5 關注與領域有關的規則
7.5.1 需要合作的規則
7.5.2 使用基於集合的處理方法
7.5.3 基於服務的驗證
7.5.4 在不應該轉換時嘗試轉換
7.5.5 業務ID
7.5.6 避免問題
7.5.7 再次將聚合作為工具
7.6 擴展API
7.6.1 查詢用於設定UI的規則
7.6.2 使注入規則成為可能
7.7 對實現進行精化
7.7.1 一個初步實現
7.7.2 創建規則類,離開最不成熟的階段
7.7.3 設定規則列表
7.7.4 使用規則列表
7.7.5 處理子列表
7.7.6 一個API改進
7.7.7 自定義
7.7.8 為使用者提供元數據
7.7.9 是否適合用模式來解決此問題
7.7.10 複雜規則又是什麼情況
7.8 綁定到持久化抽象
7.8.1 使驗證接口成為可插入的
7.8.2 在保存方面實現被動驗證的替代解決方案
7.8.3 重用映射元數據
7.9 使用泛型和匿名方法
7.10 其他人都做了什麼
7.11 小結
第三部分 套用PoEAA
第8章 用於持久化的基礎架構
8.1 持久化基礎架構的需求
8.2 將數據存儲到哪裡
8.2.1 RAM
8.2.2 檔案系統
8.2.3 對象資料庫
8.2.4 關係資料庫
8.2.5 使用一個還是多個資源管理器
8.2.6 其他因素
8.2.7 選擇和前進
8.3 方法
8.3.1 自定義手工編碼
8.3.2 自定義代碼的代碼生成
8.3.3 元數據映射(對象關係(O/R)映射工具)
8.3.4 再次選擇
8.4 分類
8.4.1 領域模型風格
8.4.2 映射工具風格
8.4.3 起點
8.4.4 API焦點
8.4.5 查詢風格
8.4.6 高級資料庫支持
8.4.7 其他功能
8.5 另一個分類:基礎架構模式
8.5.1 元數據映射:元數據的類型
8.5.2 標識欄位
8.5.3 外鍵映射
8.5.4 嵌入值
8.5.5 繼承解決方案
8.5.6 標識映射
8.5.7 操作單元
8.5.8 延遲載入/立即載入
8.5.9 並發控制
8.6 小結
第9章 套用NHibernate
9.1 為什麼使用NHibernate
9.2 NHibernate簡介
9.2.1 準備
9.2.2 一些映射元數據
9.2.3 一個小的API示例
9.2.4 事務
9.3 持久化基礎架構的需求
9.3.1 高級持久化透明
9.3.2 持久化實體的生命周期所需的特定特性
9.3.3 謹慎處理關係資料庫
9.4 分類
9.4.1 領域模型風格
9.4.2 映射工具風格
9.4.3 起點
9.4.4 API焦點
9.4.5 查詢語言風格
9.4.6 高級資料庫支持
9.4.7 其他功能
9.5 另一種分類:基礎架構模式
9.5.1 元數據映射:元數據類型
9.5.2 標識欄位
9.5.3 外鍵映射
9.5.4 嵌入值
9.5.5 繼承解決方案
9.5.6 標識映射
9.5.7 操作單元
9.5.8 延遲載入/立即載入
9.5.9 並發性控制
9.5.10 額外功能:驗證掛鈎
9.6 NHibernate和DDD
9.6.1 程式集概覽
9.6.2 ISession和存儲庫
9.6.3 ISession、存儲庫和事務
9.6.4 得到了什麼結果
9.7 小結
第四部分 下一步驟
第10章 博採其他設計技術
10.1 上下文為王
10.1.1 層和分區
10.1.2 分區的原因
10.1.3 限界上下文
10.1.4 限界上下文與分區有何關聯
10.1.5 向上擴展DDD項目
10.1.6 為什麼對領域模型——SO分區
10.2 SOA簡介
10.2.1 什麼是SOA
10.2.2 為什麼需要SOA
10.2.3 SOA有什麼不同
10.2.4 什麼是服務
10.2.5 服務中包括什麼
10.2.6 深入分析4條原則
10.2.7 再來看一下什麼是服務
10.2.8 OO在SOA中的定位
10.2.9 客戶-伺服器和SOA
10.2.10 單向異步訊息傳遞
10.2.11 SOA如何提高可伸縮性
10.2.12 SOA服務的設計
10.2.13 服務之間如何互動
10.2.14 SOA和不可用的服務
10.2.15 複雜的訊息傳遞處理
10.2.16 服務的可伸縮性
10.2.17 小結
10.3 控制反轉和依賴注入
10.3.1 任何對象都不是孤島
10.3.2 工廠、註冊類和服務定位器
10.3.3 構造方法依賴注入
10.3.4 setter依賴注入
10.3.5 控制反轉
10.3.6 使用了Spring . NET框架的依賴注入
10.3.7 利用PicoContainer . NET進行自動裝配
10.3.8 嵌套容器
10.3.9 服務定位器與依賴注入的比較
10.3.10 小結
10.4 面向方面編程
10.4.1 熱門話題有哪些
10.4.2 AOP術語定義
10.4.3 .NET中的AOP
10.4.4 小結
10.5 小結
第11章 關注UI
11.1 提前結語
11.2 模型-視圖-控制器模式
11.2.1 示例:Joe的Shoe Shop程式
11.2.2 通過適配器簡化視圖界面
11.2.3 將控制器從視圖解耦
11.2.4 將視圖和控制器結合起來
11.2.5 是否值得使用MVC
11.3 測試驅動的Web窗體
11.3.1 背景
11.3.2 一個示例
11.3.3 領域模型
11.3.4 GUI的TDD
11.3.5 Web窗體實現
11.3.6 小結
11.3.7 用NMock創建模擬
11.4 映射和包裝
11.4.1 映射和包裝
11.4.2 用表示模型來包裝領域模型
11.4.3 將表示模型映射到領域模型
11.4.4 管理關係
11.4.5 狀態問題
11.4.6 最後的想法
11.5 小結
11.6 結束語
第五部分 附錄
附錄A 其他領域模型風格
附錄B 已討論的模式的目錄
序言
構建企業應用程式並非易事。儘管我們擁有大量工具和框架來簡化這項任務,但仍然需要弄清楚如何更好地使用這些工具。大量方法可供我們選用,但關鍵是要知道在特定情況下應使用哪種方法,因為一種方法很難適用於所有情況。在過去幾年中,有一個社區逐漸成長起來,人們不斷尋找用於設計企業套用的方法,並以模式的形式將它們記錄下來。參與這項工作的人們(例如我)試圖找到公共方法,並描述如何更好地使用它們,以及它們何時適用。最後的結果過於寬泛,會導致為讀者提供了過多的選擇。
當我開始創作Patterns Df Enterprise Application Architecture(《企業套用架構模式》,Addison.’Wesley公司2002出版)時,我曾在微軟技術方面尋找過這種類型的設計建議。幾經努力之後幾乎一無所獲,只找到了一本討論此領域的書,就是Jimmy的前一本書。我喜歡他平易近人的寫作風格,也喜歡他深入挖掘易被他人忽略的概念的熱情。因此,Jimmy決定從我和企業模式社區中的其他人借鑑一些思想,並向讀者展示在編寫.NET應用程式時如何套用這些思想,我覺得再合適不過了。
文摘
第一部分 背景知識第1章 應重視的價值,也是對過去幾年的沉重反思
本章的目的是布置場景。本章將回顧過去幾年中我如何思考不同概念,以及我的思想是如何隨時間改變的。
我們將圍繞很多話題討論並涵蓋大量基礎知識,但總體思想是討論在架構和開發過程方面應該重視的價值。
在這個過程中,我們將介紹並討論很多概念,本書後面將對這些概念進行深入討論。
那么,讓我們開始吧!
1.1 總體價值
過去,我很擅長提前計畫。我經常前瞻性地為項目添加功能、結構和機制。所添加的工件本身是非常好的,但我總是忘記它們從未發揮任何好的作用。當然,我也為項目增加了不少負擔。成本是相當高的,包括開發時間和增加的複雜性。
在過去幾年中,我們被鼓勵使用另一種方法:“做可能管用的最簡單的事。”在很大程度上,這個思想來源於極限編程( Extreme Programmin9,XP)運動[Beck xP]。另一種非常類似的說法是“你將不需要它”( YouAren’tGoingtoNeedIt,YAGNI),這是幫助人們保持循規蹈矩的一種好方法。我猜想“保持簡單,傻瓜”( Keep It Simple Stupid,KISS)也應屬於此類。
這兩種方法( 預先添加所有能想到的與做最簡單的事)是兩個極端,但我認為它們都忽略了某些事情,即沒有考慮到折中。正如所有關於“這個最好,還是那個最好”的問題一樣,答案是“它取決於什麼條件”。這是一個有關折中的問題。我傾向於選擇這二者中間某個位置的方法,並根據情況選擇向哪個方向偏移。“lagom”這個詞是一個瑞典語單詞,它表示“剛剛好”或“不多也不少”這樣的意思。Lagom或“保持平衡”連同上下文敏感性就是我認為應該重視的總體價值,還有就是持續學習。
讓我們更仔細地觀察一些更具體的價值領域( 架構和過程組成),我們從架構開始,以便將我們引入正確的語境。