《Microsoft .NET 企業級應用架構設計》 - 學習筆記

来源:https://www.cnblogs.com/GATTACA2011/archive/2020/07/23/13364186.html

《Microsoft .NET 企業級應用架構設計》 [作者] (意) Dino Esposito (意) Andrea Saltarello[譯者] (中) 陳黎夫[出版] 人民郵電出版社[版次] 2010年06月 第1版[印次] 2010年06月 第1次 印刷[定價] 69.00元 【前言】 ( ...


《Microsoft .NET 企業級應用架構設計》

========== ========== ==========
[作者] (意) Dino Esposito (意) Andrea Saltarello
[譯者] (中) 陳黎夫
[出版] 人民郵電出版社
[版次] 2010年06月 第1版
[印次] 2010年06月 第1次 印刷
[定價] 69.00元
========== ========== ==========

【前言】

(P001)

每次遇到軟體項目時,我們都會創建一個解決方案。這個過程就叫做架構設計,而架構設計的最終產物就是軟體架構。

架構是一個系統中最為核心的部分,是構造系統過程中的支柱。

【第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 模式提供了一個最佳的可測試性、分離關註點、維護性和代碼重用的組合。


您的分享是我們最大的動力!

更多相關文章
  • 室內地圖製作經過易景空間地圖團隊的持續優化迭代,新版本地圖編輯器中的畫圓柱體、模型庫、快速畫道路、房間直接換紋理貼圖等功能終於上線了,目前市面上一款無需安裝軟體就能直接使用瀏覽器訪問的線上室內地圖製作編輯器。 ...
  • 摘要 重裝電腦系統後,使用npm install初始化項目依賴失敗了,錯誤提示:'proxy' config is set properly..........,具體的錯誤提示如下圖所示: 解決方案 經過報錯信息查詢解決辦法,最終找到了兩個比較好的方案,在此總結一下,以便下次再遇到此類問題。 方案一 ...
  • 引入Javascript的發展史 JavaScript的基本語法篇 1.與HTML結合的方式 2.0 註釋與數據類型 3.0 變數 4.0 運算符 (1)一元運算符 (2)比較運算符 (3)邏輯運算符 (4)三元運算符 5.流程式控制制語句 6.JS特殊語法 練習:在頁面上列印一個99乘法表 <!DOC ...
  • 隨著我國經濟的飛速發展,三維地下管網、地下管線系統直觀高效的參考,結合GIS、資料庫和三維技術,直觀顯示地下管線的空間層次和位置信息,資源的統籌利用審批工作提供準確,易景空間地圖專業致力於三維管網、管網建模、bim管線、三維管網檢測提供專業的技術服務,數據驅動快速生成三維管網矢量模型。 ...
  • 一,效果圖。 二,代碼。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>CSS 偽類</title> <style> a:link { color: #FF0000; } /* unvisited link */ a:visi ...
  • 前言 本篇文章收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與演算法的知識。 你好,我是彤哥,一個每天爬二十六層樓還不忘讀源碼的硬核男人。 前面幾節,我們一起學習了演算法的複雜度如何分析,並從最壞、平均、最好以及不能使用最壞情況全方位無死角的剖析了演算法的複雜度,在我們表示覆雜度的 ...
  • //記錄滑鼠按下 public static bool MouseBtnIsDown = false; //截圖起始坐標 public static Point StartPoint; //截圖的長寬 double width = 0; double height = 0; //滑鼠按下事件 pub ...
  • 前言 本篇文章收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與演算法的知識。 你好,我是彤哥,一個每天爬二十六層樓還不忘讀源碼的硬核男人。 上一節,我們從最壞、平均、最好三種情況分析了演算法的複雜度,得出結論,通常來說,使用最壞情況來評估演算法的複雜度完全夠用了。 但是,有些演算法是 ...
一周排行
  • 比如要拆分“呵呵呵90909086676喝喝999”,下麵當type=0返回的是中文字元串“呵呵呵,喝喝”,type=1返回的是數字字元串“90909086676,999”, private string GetStrings(string str,int type=0) { IList<strin ...
  • Swagger一個優秀的Api介面文檔生成工具。Swagger可以可以動態生成Api介面文檔,有效的降低前後端人員關於Api介面的溝通成本,促進項目高效開發。 1、使用NuGet安裝最新的包:Swashbuckle.AspNetCore。 2、編輯項目文件(NetCoreTemplate.Web.c ...
  • 2020 年 7 月 30 日, 由.NET基金會和微軟 將舉辦一個線上和為期一天的活動,包括 微軟 .NET 團隊的演講者以及社區的演講者。本次線上大會 專註.NET框架構建微服務,演講者分享構建和部署雲原生應用程式的最佳實踐、模式、提示和技巧。有關更多信息和隨時瞭解情況:https://focu... ...
  • #abp框架Excel導出——基於vue #1.技術棧 ##1.1 前端採用vue,官方提供 UI套件用的是iview ##1.2 後臺是abp——aspnetboilerplate 即abp v1,https://github.com/aspnetboilerplate/aspnetboilerp ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:碧茂大數據 PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取 input()輸入 Python提供了 input() 內置函數從標準輸入讀入一 ...
  • 從12年到20年,python以肉眼可見的趨勢超過了java,成為了當今It界人人皆知的編程語言。 python為什麼這麼火? 網路編程語言搜索指數 適合初學者 Python具有語法簡單、語句清晰的特點,這就讓初學者在學習階段可以把精力集中在編程對象和思維方法上。 大佬都在用 Google,YouT ...
  • 在社會上存在一種普遍的對培訓機構的學生一種歧視的現象,具體表現在,比如:當你去公司面試的時候,一旦你說了你是培訓機構出來的,那麼基本上你就涼了,那麼你瞞著不說,然後又通過了面試成功入職,但是以後一旦在公司被髮現有培訓經歷,可能會面臨被降薪,甚至被辭退,培訓機構出來的學生,在用人單位眼裡就是能力低下的 ...
  • from typing import List# 這道題看了大佬寫的代碼,經過自己的理解寫出來了。# 從最外圍的四周找有沒有為O的,如果有的話就進入深搜函數,然後深搜遍歷# 判斷上下左右的位置是否為Oclass Solution: def solve(self, board: List[List[s ...
  • import requests; import re; import os; # 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, li ...
  • import requests; import re; import os; import parsel; 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537. ...