**《Microsoft .NET 企業級應用架構設計》前端
========== ========== ==========
[做者] (意) Dino Esposito (意) Andrea Saltarello
[譯者] (中) 陳黎夫
[出版] 人民郵電出版社
[版次] 2010年06月 第1版
[印次] 2010年06月 第1次 印刷
[訂價] 69.00元
========== ========== ==========數據庫
【前言】 編程
(P001) 設計模式
每次遇到軟件項目時,咱們都會建立一個解決方案。這個過程就叫作架構設計,而架構設計的最終產物就是軟件架構。api
架構是一個系統中最爲核心的部分,是構造系統過程當中的支柱。瀏覽器
【第01章】 【當代的架構師和架構】 安全
(P003) 服務器
在軟件領域中,架構就是指爲客戶構建系統。網絡
(P004) 數據結構
優秀的架構師是團隊所必需的。那麼什麼是優秀呢?這我的必須有豐富的經驗、良好的教育以及相應的資格。
當代系統須要不少的工程以及理解,但不須要太多藝術和主觀的猜想,這正是優秀架構師應當努力的方向。
(P007)
描述架構的一種很是流行的方法是使用 UML 圖表。
(P009)
架構將被精煉到真正重要的事情上 —— 不管這事情是什麼。
(P010)
領域驅動設計理論實際上建議老是使用工廠來建立複雜的對象。
通常來講,使用 virtual 或 sealed 修飾符須要承擔很多的責任。
(P015)
架構設計要基於對需求的分析,分析會決定系統將要作什麼,而架構則決定系統如何作。
(P017)
架構師最終將負責系統的開發,並與開發者團隊協調,技術詳細說明書正是架構師和開發者溝通並傳達架構的工具。
溝通是架構師的關鍵。架構師須要與開發者溝通,也須要與項目經理和分析師溝通,或許還要與用戶溝通。架構師很重要的一個技能就是語言要明確清晰。
(P018)
架構師不過就是一個優秀一些,更有經驗的開發者而已。
(P019)
一般而言,分析應屬於項目領域中的專家,而架構師無需如此。分析師能夠告訴架構師他對系統的理解,包括系統如何工做以及系統須要作什麼等。
(P020)
架構師和開發者之間的區別就在於經驗和教育經歷。
【第02章】 【UML 必要知識】
(P028)
UML 基於一系列的圖形化標記,特別適合在面向對象場景中建模。
(P029)
建模對於任何軟件項目來講都是個核心步驟,對於大型的企業級應用程序 (特別是那些支撐公司正常運做的程序) 來講,其做用更加不容忽視。
在軟件領域中,模型應該與建築中的導航圖、計劃圖和物理模型同樣重要 —— 這是必須而不是可選的。
【第03章】 【設計原則和模式】
(P056)
一個設計精良的系統並非一系列指令和修補的堆砌,裏面還有不少與設計直接或間接相關的東西。
一個良好的代碼體系能夠容易地找到 Bug 所在,也能夠輕易地修復 Bug ,還能夠在任什麼時候候進行任何程度的改進,包括可擴展性和可伸縮性。考慮到這些,可維護性就成爲了設計系統時最應該關注的問題。
(P060)
高內聚的模塊意味着高的可維護性和可重用性,由於這些模塊的外部依賴不多。
(P061)
模塊之間顯然須要通訊,不過通訊應該依賴於一系列設計良好且不易改變的接口。
低耦合和高內聚脣齒相依。若系統知足了這兩個條件,那麼一般來講該系統已經基本知足了高可讀性、高可維護性、易於測試和易於重用的要求。
分離關注點的核心在於將系統拆分紅各不相同且最好沒有重疊的功能。每一個系統中的功能都表示了一個關注點,即系統的一個方面。
(P062)
分離關注點是經過模塊化代碼以及大量運用信息隱藏來實現的。
(P063)
在過程式編程中,分離關注點是依靠函數和過程來實現的。
(P065)
面向對象設計的基本原則能夠總結成 3 條 : 找到合適的對象、儘可能下降耦合和儘可能保證代碼重用。
(P068)
基於接口,而不是實現編程。
(P070)
儘可能使用對象組合,而不是類型繼承。
(P072)
模塊應該對擴展開放,但對修改關閉。
(P074)
開放 / 封閉 原則和里氏替換原則有着緊密的關係。任何使用了某個違反里氏替換原則的類型的方法都沒法知足 開放 / 封閉 原則。
(P076)
高層次組件不該該依賴於低層次組件,兩者均應依賴於接口。抽象不該該依賴於細節,細節應該依賴於抽象。
(P080)
使用設計模式在本質上並不能讓你的解決方案更有價值,真正的價值在於,在交付的時候你的解決方案是否能正常工做並知足需求。
(P084)
慣用法是一個硬式編碼在編程語言或實如今 框架 / 技術 中的模式。
慣用法是一種充分利用語言能力,並從代碼中獲取期待的行爲的作法。
(P086)
推薦在公開簽名中使用 IList<T> 或其派生接口,或者使用實現了 IList<T> 接口的自定義類型。
(P088)
全部的 IoC 框架都基於一個容器對象構造,這個容器對象將和一些配置信息綁定,並解析依賴。調用者代碼將實例化容器,並將須要的接口以參數的形式傳入。做爲響應, IoC / DI 框架將返回一個實現了該接口的具體對象。
【第04章】 【業務層】
(P121)
業務層是全部分層系統的核心,包含了系統的核心邏輯。
(P123)
業務邏輯層處於分層系統的中間位置,負責表現層和數據訪問層之間的信息交換。
不少時候,架構師更傾向於使用數據遷移對象 (Data-Transfer Object , DTO) 在層之間交換數據。
業務對象同時包含了數據和行爲,是一個能夠參與到領域邏輯中的完整對象。
數據遷移對象更像是一種值對象 —— 即一系列數據的容器而沒有相關的行爲。
爲了序列化,業務對象中的數據會複製到數據遷移對象中。
數據遷移對象僅僅是所須要部分數據的投影而已。
(P125)
工做流與普通類型的不一樣之處在於,它容許經過邏輯上的圖表來表達任意的邏輯。
(P126)
對於 Tier ,咱們用其表示系統中的物理上的硬件和軟件,由執行一樣功能的一臺或多臺服務器定義。相反地, Layer 用來表示系統中完成指定任務的邏輯部分。
Layer 通常用來組織代碼,而 Tier 則是指代碼運行的位置。
多個 Layer 能夠共存於同一個物理 Tier 上。同時,某個 Layer 也應該能夠輕易地移動到另外一個 Tier 上。
每一個層都有能夠看作是一個黑盒,這個黑盒對輸入和輸出有着定義清晰的契約 (接口) ,且沒有或不多依賴於其餘層以及物理服務層。
分層帶來的好處主要是條理清晰,且有利於重用以及分離關注點。
分離關注點建議層應該有良好的封裝,或者說高內聚低耦合。
良好的可重用性加上正確地對功能進行拆分將大大下降系統的維護成本。
(P127)
物理層中一個重要的概念是,一個層就表示一個須要穿過的邊界,這個邊界多是進程邊界或計算機邊界。穿過邊界是個代價很高的操做,若須要到達遠程計算機,那麼代價要比到達同一臺計算機中不一樣的進程高。一個估算比例是穿越進程邊界要比進程內部調用慢 100 倍左右。若須要經過網絡訪問,還要更慢一些。
咱們應該儘量地下降物理層的數目。添加一個新的物理層以前,必需要通過仔細的成本收益分析,這樣作的代價大多在於增長了複雜性,而優點通常體如今安全性、可伸縮性以及容錯性上。
(P128)
遠程使用的業務邏輯層必需要由一個粗粒度的接口封裝起來 —— 通常使用門面 (Facade) 模式。
對於那些不是一直在線的應用程序來講,將業務邏輯層部署到客戶端是必須的。
業務邏輯層不該該看作是一個總體的組件,或者一些不相關模塊的組合。多年的實際經驗告訴咱們,業務邏輯在其餘層 (指經典的 3 層架構) 中的適當重複是能夠接受的,也是不少現實程序的作法。不過這種作法有必定的限度,且不該該受到鼓勵。
(P129)
分散在表現層和數據訪問層中的邏輯有可能只是出於性能方面的考慮才進行的重複。
(P130)
數據訪問層須要瞭解的僅僅是如何獲取記錄,須要檢查的是數據類型以及可控性,須要確保的是數據完整性和索引。
你應該僅僅把存儲過程當作一個數據庫工具,而不是做爲業務邏輯的表達工具。
(P132)
歷史上,事務腳本是第一個被普遍應用的業務邏輯模式。若干年後,另外一種基於表數據的模式逐漸浮出水面,名爲表模塊 (Table Module) 。表模塊的設計角度還是一系列事務,不過事務是按照數據分組的。
最簡單的對象模型看上去就像是數據庫表的數據模型,這裏組成模型的對象就是數據庫中的記錄,並加了一些額外的方法。這個模式一般叫作活動記錄 (Active Record) 。
(P133)
領域驅動的設計必定會使數據模型和領域模型之間存在着不小的差別。這個模式一般叫作領域模型 (Domain Model) 。
總而言之,若你感受更應該關注於操做,能夠選擇事務腳本模式。若以數據表的形式考慮更方便,那麼選擇表模塊模式。若領域模型與數據模型很是類似,那麼活動記錄模式可能更適合使用。而若建模的過程須要從各個相關對象開始,並劃分紅衆多子系統,則能夠選擇領域模型模式。
(P134)
一旦你對領域模型模式有了足夠的瞭解,不管系統的複雜性如何,你均可以使用領域模型模式。
過程式模式在達到某種程度以後,其添加功能帶來的複雜性會以指數方式增加。
(P135)
事務腳本 (Transcation Script) 模式多是業務邏輯層中最簡單的模式了,它是一個純粹的過程式模式。
事務腳本模式鼓勵你放棄全部的面向對象設計,將業務組件直接映射到須要的用戶操做上。
(P136)
事務腳本適合應用於那些業務邏輯很是簡明直白,且最好不大可能改變的簡單場景中。
簡單是事務腳本最值得一提的優點,它沒有開始時的額外代價,且能夠和快速應用程序開發 (Rapid Application Development, RAD) 環境良好地配合。
對於邏輯很少、時間緊迫且依賴於強大的集成化開發環境 (如 Visual Studio) 的項目,事務腳本是其理想的選擇。
(P146)
若系統中的表現層和數據訪問層都是基於表狀數據結構,那麼表模式將是很是好的選擇。
(P151)
DataSet 的核心功能是一個數據容器,專門用來管理表格狀數據,其中的名詞也使用了表、列和行等相似數據庫的概念。DataSet 並不瞭解爲其提供數據的對象,且 DataSet 可被序列化。
DataSet 要配合其餘數據表相關的對象 (例如, DataTable 、 DataRow 和 DataRelation ) 工做。 DataSet 中包含了一系列數據表的集合以及這些表之間的關係,而 DataTable 中則包含了一個數據行的集合,以及相關的約束和索引信息。
(P157)
活動記錄 (Active Record , AR) 是一種應用於相對簡單的領域模型,但仍舊基於對象的模式。
活動記錄基於數據表中的行,而不像表模塊那樣基於數據表。
活動記錄對數據有行級別的粒度,而表模塊關注的是整個數據表。
活動記錄就是指一個封裝了數據庫表或視圖的一行的對象,對象中能夠同時包含數據 (列中的值) 和行爲 (包含邏輯的方法) 。
活動記錄對象中一般會包含用來執行經常使用查詢的查找方法、 CRUD 操做、驗證以及領域相關的計算和檢查功能。
(P158)
活動記錄很是適合於不少的 Web 站點,由於不管其中涉及多少個數據表,其業務實體和關係型數據表的結構大多比較相似。
(P167)
在設計領域邏輯時,若選用了過程式方法或活動記錄模式,那麼實際上採起的是以數據爲核心的作法。
在數據爲核心的方法中,咱們通常從數據庫開始設計,隨後根據所須要的操做 (最終會操做數據庫) 或數據表進行業務組件的建模。
(P168)
領域驅動設計實際上是一種考慮問題的方法 —— 一種將問題領域放在全部事情中首要位置的方法。
(P169)
領域模型能夠看作是活動記錄的「大哥」。領域模型徹底與數據庫獨立,是一個儘量貼近真實流程的模型,而不是去貼近架構師但願的流程。
(P180)
倉儲模式在領域模型和數據訪問代碼之間添加了另外一個抽象的類。
【第05章】 【服務層】
(P186)
服務層能夠看作是表現層結束、業務邏輯層開始的一個邊界,服務層用來儘量地下降表現層和業務邏輯之間的耦合,讓表現層無需關注業務邏輯層中的具體實現組織方式。
(P188)
服務層位於系統中的兩個互相通訊的邏輯層之間,使兩個層可以在鬆散耦合並優美地彼此分離開的同時,仍舊能夠完美地彼此通訊。
服務層將組織業務邏輯層中的組件 —— 包括服務、工做流和領域模型中的對象,並根據須要調用數據訪問層。
業務邏輯層中惟一須要徹底和數據庫細節分離的部分就是領域模型。
服務層是表現層和其餘層之間的邊界,理論上服務層應該經過數據遷移對象與表現層交互,並在內部根據須要將其轉換成領域模型類。服務層中暴露的每一個方法都組織使用到其餘服務,包括工做流,以及經過數據映射器或 對象 / 關係映射器 (Object / Relational Mapper, O/RM) 支持的語言執行數據庫操做。
(P189)
服務層從表現層中獲得輸入,並組織工做流、服務和數據訪問組件。
一般來講,服務層就是一系列暴露了邏輯上相關方法的類,供其餘層 (一般是表現層) 調用。
(P191)
在設計應用程序時,面向服務容許使用獨立的組件並同時提供固定的公開接口,這些組件能夠隨時被替換,只要與其餘組件的契約不變,就不會影響到系統的功能。
(P192)
從架構上講,服務層應用了軟件設計中一個通用且人人皆知的原則 —— 低耦合,可能還應用了另外一個原則 —— 高內聚,這是經過一箇中間層解除用戶界面和中間層的耦合來實現的。
服務層中的服務將被表現層直接調用,在 Web 前端中,也就是頁面的代碼後置 (Code-behind) 類將調用服務層。
(P193)
MVP 模式的實現能確保在 Windows 窗體或 Web 頁面加載以後能夠當即獲得一個展現器對象,這一般使用依賴注入實現。
(P195)
服務層爲用戶界面和中間層提供了一個統一的契約,所以中間層便可專一於實現應用邏輯 (Application Logic) 。
(P198)
服務層添加了額外的抽象併除去了兩個交互層之間的耦合,若這一點在你的系統中比較重要,那麼應該建立服務層。服務層能夠幫助你實現一個粗粒度的遠程接口,並下降表現層與業務層之間的通訊流量。
(P199)
若你對 .NET Framework 有所瞭解,那麼應該知道建立服務 (WCF 或 Web 服務) 就是個普通的類加上一些特性修飾而已。
服務歸根到底就是一個附加了一些東西的類。
(P203)
服務層是經過一系列的 (服務) 類集合來把方法暴露給用戶界面的。
(P236)
若想在瀏覽器中的頁面裏調用 Web 或 WCF 服務,必須使用一個代理類。該代理類就是一個 JavaScript 類,將在訪問某個特定的 URL 時由服務的運行時生成。
(P237)
JSON 是一個新的標準,用於以腳本方式發出請求時瀏覽器和 Web 服務器之間經過 HTTP 交換數據。 JSON 優於 XML 的最主要緣由能夠總結爲 JSON 要比發展成熟的 XML 更加簡單,且在全部支持 JavaScript 的瀏覽器中都有免費的內建反序列化引擎。
【第06章】 【數據訪問層】
(P244)
數據訪問層是系統中惟一知道並使用鏈接字符串和數據表名稱的地方。
(P245)
數據訪問層將對象模型保存至數據庫中,並根據數據庫中的數據建立類型實例。
(P246)
數據訪問層是系統中惟一能夠操做數據庫的一層,系統的其餘部分也不該該包含任何有關數據庫的信息。
(P248)
倉儲是一個用來放置對指定對象進行經常使用查詢的類。
(P256)
面向數據訪問層接口編程,而不是面向數據訪問層實現。
(P266)
微軟的 Unity Application Block (簡稱 Unity) 就是一個輕量級的依賴注入容器,支持構造函數、屬性和方法調用的注入, Unity 隨 Enterprise Library 4.0 一塊兒發佈。
(P271)
若需求不容許你使用商業或免費的 O/RM ,也必需要手工建立數據訪問層。
(P334)
NHibernate 徹底支持 POCO 對象,而 LINQ-to-SQL 和 EF 則沒法作到。
【第07章】 【表現層】
(P345)
表現層由兩個主要組件組成 : 用戶界面和表現層邏輯 (也叫作 UI 邏輯) 。
表現層邏輯將負責中間層和 UI 之間數據流的交互。
(P346)
表現層的職責應該從更高的角度考慮,即不依賴於物理 UI 、較高可測試性和不依賴於數據模型。
一個設計良好的表現層會讓開發者在開發週期中更容易地切換到不一樣的 UI 。
(P349)
架構師的主要職責是保證產品知足了全部的重要質量特質 (特別是可用性和可訪問性) 。
表現層邏輯的最終目標是確保視圖中的數據能夠正確地 流入 / 流出 。
(P351)
自治視圖目前已經再也不流行,最主要的緣由就是它難以測試。
咱們並非生活在完美的世界中,這也就意味着與理想狀況相比,咱們須要更多的讓步。
(P352)
在設計系統的表現層時,有一個基本的原則須要遵照,那就是讓表現層和程序其餘部分徹底分離,包括業務層和數據訪問層。
(P356)
MVP 更加適合於大型、複雜的應用程序。
(P358)
視圖的另外一個關鍵職責是呈現。
(P369)
無論怎樣, MVP 並不建議應用於任意的程序上。
(P373)
對於那些須要支持多個 GUI 的場景,可能惟一的選擇就是 MVP 模式了。 MVP 模式提供了一個最佳的可測試性、分離關注點、維護性和代碼重用的組合。**