成功應用程序的模式_第1頁
成功應用程序的模式_第2頁
成功應用程序的模式_第3頁
成功應用程序的模式_第4頁
成功應用程序的模式_第5頁
已閱讀5頁,還剩5頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、1第 章成功應用程序的模式本章內容: 介紹“四人組”(Gang of Four,GoF)設計模式 概述一些常見的設計原則和SOLID設計原則 描述Fowler企業模式約翰列儂曾經寫道“沒有問題,只有出路”。現在,雖然據我所知列儂先生從未從事ASP.NET編程,但是在軟件開發甚至人性方面(但這超出了本書的研究范疇),他所說的這句話卻極為中肯。作為軟件開發者,我們的工作涉及解決問題,而之前已經有其他開發者曾經無數次不得不解決這些問題,雖然這些問題披著各式的外衣。自從面向對象編程方法出現以來,人們已經發現、命名和歸類許多模式、原則和最佳實踐。了解了這些模式和常見解決方法詞匯表,就可以著手將復雜問題分

2、解,將不同部分封裝起來,并采用經過檢驗的可信解決方案,以一種統一的方式來開發應用程序。本書的目標是介紹可以運用到ASP.NET應用程序中的設計模式、原則和最佳實踐。本質上,對于設計模式和原則,其語言可以是不可知的,因此可以把從本書學到的知識運用到WinForm、WPF和Silverlight應用程序以及其他優秀的面向對象語言。本章將介紹設計模式的定義、起源以及學習它們的重要性。設計模式的基礎是堅實的面向對象設計原則,本章將以Robert Martin的S.O.L.I.D.設計原則為例來講解這一點。本章還將介紹Martin Fowler的Patterns of Enterprise Applic

3、ation Architecture一書中提出的一些更高級的模式。1.1 設計模式釋義設計模式是高層次的、抽象的解決方案模板。可以將這些模式視為解決方案的藍本而不是解決方案本身。從中無法找到一種可以簡單地運用到應用程序中的框架;相反,通常是通過重構自己的代碼并將問題泛化來實現設計模式。設計模式不僅適用于軟件開發領域,從工程到建筑的所有領域都能夠找到它的身影。實際上,模式的思想是由著名建筑大師Christopher Alexander在20世紀70年代引入的,目的是為設計討論構建一張公共的詞匯表。他寫道:本語言的元素是被稱為模式的實體。每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題

4、的解決方案的核心,這樣就可以一次又一次地使用該方案而不必做重復勞動。Alexander的觀點不僅適用于建筑和城市規劃,也適用于軟件設計。1.1.1 起源當今軟件體系結構中比較流行的設計模式起源于程序員多年使用面向對象編程語言而積累的經驗和知識。Design Patterns: Elements of Reusable Object-Oriented Software(又被親切地稱為Design Patterns Bible,即“設計模式圣經”)一書收錄了絕大多數最常見的模式。這本書是由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四人

5、合著而成,而他們常被稱為“四人組”(GoF)。他們收錄了23種設計模式并將它們歸納為3組。 創建型模式:處理對象構造和引用。 結構型模式:處理對象之間的關系以及它們之間如何進行交互以形成更大的復雜對象。 行為型模式:處理對象之間的通信,特別是在責任和算法方面。所有模式均采用模板表達,這樣讀者就可以學習如何解讀模式并加以運用。我們將在第2章中講解使用設計模式模板所需的實用知識,并簡要介紹將要在本書剩余部分學到的所有模式。1.1.2 必要性模式對于軟件設計和開發而言至關重要。不管是在設計階段解決問題,還是在源代碼中,模式都支持通過共享的詞匯表來表達思想。模式提倡使用優秀的面向對象軟件設計,這是因為

6、它們是圍繞可靠的面向對象設計原則而構建的。模式是描述復雜問題的解決方案的有效方式。如果具備設計模式的牢固知識,就可以與團隊中的其他成員快速、順暢地溝通,而不必糾結于底層的實現細節。模式是語言不可知的,因此,可以將它們轉換成其他面向對象語言。通過學習模式而獲得的知識將能夠運用于具體編程時采用的任何優秀的面向對象語言。1.1.3 有效性設計模式的使用價值和終極價值在于,它們是可靠的、經過驗證的解決方案,它們的有效性毋庸置疑。如果是一名經驗豐富的開發者并且已經采用.NET或其他面向對象編程語言從事編程工作多年,或許發現自己已經在使用“GoF”書中提及的一些設計模式。但如果能夠辨別正在使用的模式,那么

7、與其他同樣理解模式的開發者的溝通效率就會高得多,他們會理解您的解決方案的結構。設計模式的宗旨就是重用解決方案。當然,并非所有問題都是一模一樣的,但如果能夠將一個問題分解,并找出它與以前解決過的問題之間的相似之處,就可以運用這些解決方案。經過數十年的面向對象編程實踐,所遇到的大多數問題在之前已經被解決過無數次,而且會有一種模式可用于幫助您實現解決方案。即使您認為自己遇到的問題是獨特的,也應該可以通過將其分解成若干基本要素,將其泛化至一定程度,從而找出一種合適的解決方案。設計模式的名稱非常有用,這是因為它反映出該模式的行為和目的,并為人們在集思廣益討論解決方案時提供常用的詞匯表。使用模式名稱討論,

8、要比詳細地討論其具體實現如何工作更加容易。1.1.4 局限性設計模式并非銀彈。您必須充分理解首要解決的問題,將其泛化,然后運用某個適合它的模式。但是,并非所有問題都需要設計模式。設計模式確實能夠幫助人們將復雜的問題變得簡單,但是同樣也能夠讓本來簡單的問題變得復雜。在閱讀有關模式的書籍之后,許多開發者都掉進了一個陷阱:試圖把設計模式運用到所做的每件事情,但最終取得的效果卻與設計模式初衷(也就是讓事情變得簡單)相反。前面曾經說過,運用模式的較好方法是,通過識別正在試圖解決的基本問題,來尋找適合它的解決方案。本書將幫助您識別什么時候以及如何使用設計模式,繼而從ASP.NET的角度來討論如何實現。并非

9、總要使用設計模式。如果您已經為某個問題找到一種簡單(但又不是過于簡陋的)、清晰而且可維護的解決方案,那么倘若該方案并不屬于GoF(四人組)設計模式中的某一個模式,也不要責備自己。否則,就會讓自己的設計過于復雜。這段有關設計模式的討論此時給人的感覺可能相當模糊,但是在繼續閱讀本書的過程中,您將學習每個設計模式打算解決的問題類型,并了解如何在ASP.NET中實現這些設計模式,然后就能夠將這些模式運用到自己的應用程序中。1.2 設計原則設計原則構成了設計模式賴以構建的基礎。它們要比設計模式更加基礎。通過遵循經過驗證的設計原則,自己的代碼基會變得更加靈活、更能夠適應變化,而且可維護性更佳。下面將簡要地

10、介紹一些比較著名的設計原則以及一組被稱為S.O.L.I.D.原則的原則。在本書后面將更為深入地了解這些原則,然后在ASP.NET中實現它們及最佳實踐。1.2.1 常見設計原則如同設計模式一樣,有一些常見的設計原則歷經多年已經變成了最佳實踐,并構成了企業級軟件和可維護軟件可以賴以構建的基礎。下面將預覽一些廣為人知的原則。1. 簡約原則(KISS)軟件編程領域普遍存在的一個問題是需要把解決方案過度復雜化。KISS原則的目標就是讓代碼保持簡潔但不要過于簡陋,從而避免引入任何不必要的復雜度。2. 不要重復自已(DRY)DRY原則的目的是通過將公用的部分抽離出來放在一個單獨的地方從而避免重復系統中的任何

11、部分。這個原則不僅涉及代碼而且包括系統中重復的任何邏輯。最終,系統中的任何一部分知識都應該只有一種表示形式。3. 講述而不要詢問(Tell, Dont Ask)“講述而不要詢問”原則體現了封裝以及將責任指派到正確的類這兩個思想。這個原則要求,應該告訴對象您希望它們執行什么動作,而不是詢問有關該對象狀態的問題然后由您自己決定希望執行什么動作。這個原則有助于匹配責任并避免類之間的緊密耦合。4. 您不需要它(YAGNI)YAGNI原則指的是只需要將應用程序必需的功能包含進來,而不要試圖添加任何其他您認為可能需要的功能。測試驅動開發(TDD)就是一種堅持YAGNI原則的設計方法學。TDD的宗旨就是編寫

12、測試來驗證系統的功能,然后只需要編寫可讓測試通過的代碼即可。本章稍后部分將討論TDD。5. 分離關注點(SoC)SoC這一過程將軟件分解為多項不同的功能,每項功能封裝了可供其他類使用的唯一行為和數據。通常,一個關注點代表類的一項功能或行為。將程序劃分成若干獨立職責的做法顯著提高了代碼的重用程度、維護性和可測試性。在本書剩余部分將追溯這些設計原則,這樣您就能夠了解它們是如何實現的,以及如何幫助建立干凈的、可維護的面向對象系統。下面將要看到的是S.O.L.I.D.設計原則分類中收集的設計原則。1.2.2 S.O.L.I.D.設計原則S.O.L.I.D.設計原則是一組針對面向對象設計的最佳實踐。Go

13、F設計模式均以這樣或那樣的形式遵守這些原則。術語S.O.L.I.D.來自于Robert C. Martin(朋友們親切地稱呼他Bob大叔)的著作Agile Principles, Patterns, and Practices in C#中收集的5個設計原則的名稱的首字母。下面將依次介紹這些設計原則。1. 單一責任原則(SRP)SRP原則與SoC原則保持高度一致。它要求每個對象只應該為一個元素而改變而且只有一個職責關注點。遵循這個原則,就可以避免單體類(就像是軟件領域的瑞士軍刀)設計問題。使每個類均保持簡潔,就可以提升系統的可讀性和可維護性。2. 開放封閉原則(OCP)OCP原則要求類對于擴展

14、應該是開放的,而對于修改應該是封閉的,這樣應該就能夠在不改變類的內部行為的情況下添加新功能并擴展類。這個原則努力避免破壞已有的類以及其他依賴它的類,因為這會在應用程序中造成bug和錯誤的漣漪效應。3. 里氏替換原則(LSP)LSP原則指出應該能夠使用任何繼承類來替代父類并且讓其行為方式保持不變。這個原則與OCP原則保持一致:它確保繼承類不會影響父類的行為,換句話來說,繼承類必須可替代它們的基類。4. 接口分離原則(ISP)ISP原則關注的是將契約的方法劃分成若干職責分組,并且為這些分組指派不同的接口,這樣客戶端就不需要實現一個龐大的接口和一堆它們并不使用的方法。這個原則背后的目的是:使用相同接

15、口的類只需要實現特定的一組方法,而不是實現一個龐大的單體方法接口。5. 依賴倒置原則(DIP)DIP原則的宗旨是將自己編寫的類與具體的實現隔離開來,讓這些類依賴于抽象類或接口。它提倡面向接口(而不是實現)編程,這確保代碼不會與某種實現緊密耦合,從而提高了系統的靈活性。6. 依賴注入(DI)和控制反轉(IoC)原則與DIP緊密相關的是DI原則和IoC原則。DI通過構造器、方法或屬性來提供底層類或從屬類。配合使用DI原則,這些從屬類可以被反轉為接口或抽象類,這樣就可以形成一個具有較高的可測試性和易于修改的松散耦合系統。在IoC原則中,系統的控制流與過程式編程方法相比是反轉的。這個原則的一個示例是I

16、oC容器,它的作用是將服務注入到客戶端代碼,而不必讓客戶端代碼指定具體的實現。在該實例中,控制反轉指的是客戶端獲取服務的行為。本書中,將更詳細地研究每個S.O.L.I.D.原則。但接下來,將探討一些專門用來處理特殊情況的企業級模式,它們以常見設計原則和設計模式為基礎構建。1.3 Fowler的企業設計模式Martin Fowler的著作Patterns of Enterprise Application Architecture是有關如何構建企業級應用程序的最佳實踐和模式的參考書。與GoF設計模式著作一樣,經驗豐富的開發者毫無疑問已經遵循該書中歸納的許多設計模式。但Fowler著作的價值在于,

17、在對這些模式進行分類時使用一種公用語言來描述模式。該書分為兩部分:前半部分討論n層應用程序和數據訪問、中間件以及表示層的組織;后半部分是與GoF模式著作相似的模式參考,但本書的實現更加具體。本書將討論Fowler設計模式的ASP.NET實現。下面將介紹本書剩余部分將要涉及的模式。1.3.1 分層第3章講解了在企業ASP.NET應用程序分層時可供自由采用的選項。我們將了解傳統的Web表單代碼隱藏模型帶來的問題以及如何使用傳統的分層方法將表示、業務邏輯及數據訪問等關注點分離開來。1.3.2 領域邏輯模式第4章介紹了組織業務邏輯的3種常見方法:Transaction Script(事務腳本)、Act

18、ive Record(活動記錄)及Domain Model(領域模型)。1. Transaction ScriptTransaction Script模式按照線性的、過程式方法來組織業務邏輯。它將細粒度的業務用例映射為細粒度的方法。2. Active RecordActive Record模式按照一種能夠緊密匹配底層數據結構的方式來組織業務邏輯,即表中表示數據行的對象。3. Domain ModelDomain Model模式是對現實領域對象的抽象。同時對數據和行為建模。對象之間可以存在與真實領域相匹配的復雜關系。我們將展示如何在ASP.NET中使用這些模式,以及何時適合選擇某一種模式而非其他

19、模式。1.3.3 對象關系映射在第7章中,將注意力轉向如何將業務實體的狀態持久化,以及如何從數據存儲中檢索它們。介紹以下幾種支持持久化的基礎設施代碼所需的企業模式。1. Unit of WorkUnit of Work(工作單元)模式用來維護一個由已經經過業務事務修改(添加、刪除或更新)的業務對象構成的列表。然后,Unit of Work模式負責將這些發生變化的對象的持久化工作協調成為一個原子動作。如果出現問題,整個事務就會回滾。2. RepositoryRepository(資源庫)模式大體上用于對象的邏輯集合,它們更為人知的名字叫做聚合(aggregate)。它充當業務實體的內存集合或倉庫

20、,完全將底層數據基礎設施抽象出來。3. Data MapperData Mapper(數據映射器)模式用來從原始數據中提取信息以生成對象,以及將業務對象中的信息轉換到數據庫。業務對象和數據庫彼此互不了解。4. Identity MapIdentity Map(標識映射)模式監視每一個從數據庫中加載的對象,確保所有對象只加載一次。當后面請求該對象時,在從數據庫檢索之前先檢查標志映射。5. Lazy LoadingLazy Loading(惰性加載或延遲加載)模式將獲取資源的過程推遲到真正需要用到該資源的時候。如果想象一個攜帶著通訊錄的Customer對象,那么可以從數據庫中提取這個顧客對象,但保

21、留通訊錄的生成操作,直到真正需要用到該通訊錄時才生成。這可以實現按需加載通訊錄,從而避免在從來不需要用到該地址數據時訪問數據庫。6. Query ObjectQuery Object(查詢對象)模式是GoF的Interpreter(解釋器)設計模式的一種實現。查詢對象充當一種從底層數據庫中抽象出來的面向對象查詢,它引用的是屬性和類,而不是真正的表和列。通常,還需要使用一個翻譯器對象來生成用于查詢數據庫的原生SQL語句。1.3.4 Web表示模式在第8章中,將注意力轉向企業級ASP.NET應用程序的表示需求。這一章關注的是專門用來讓業務邏輯與表示邏輯分離的模式。首先,將介紹早期Web表單開發中普

22、遍使用的代碼隱藏模型帶來的問題;然后研究那些能夠將領域和表示邏輯分離同時讓表示層能夠有效測試的模式。這些模式的任務都是將用于表示的邏輯關注點與業務邏輯關注點分離。ASP.NET表示需要所涵蓋的模式有: Model-View-Presenter(模型-視圖-表示器)。 Model-View-Controller(模型-視圖-控制器)。 Front Controller(前端控制器)。 Page Controller(頁面控制器)。1.3.5 基本模式、行為模式和結構模式在本書中,將介紹如何在企業ASP.NET應用程序中利用Fowler著作中的其他企業模式。這些模式將包括Null Object(空

23、對象)、Separated Interface(獨立接口)、Registry(注冊表)和Gateway(網關)。1. Null Object模式Null Object(空對象)模式也稱為Special Case(特殊情況)模式,它充當返回值而不是向調用代碼返回null。空對象將與預期結果共享相同的接口或者從相同的基類繼承而來,這樣減少了在代碼基中到處檢查null情況的需要。2. Separated Interface模式Separated Interface(獨立接口)模式要求將接口放在一個獨立于具體實現的程序集或命名空間中。這確保客戶端完全不知道具體實現,而且能夠遵循面向抽象編程(而不是面向

24、實現)以及依賴倒置原則。3. Gateway模式Gateway(網關)模式允許客戶端通過一個簡化的接口來訪問復雜的資源。網關對象基本上將資源API包裝成一個能夠在應用程序中到處使用的單個方法調用。此外,它還隱藏了所有的API復雜性。這里介紹的所有企業模式都將在本書中更詳細地進行討論,并有配套練習來演示如何在ASP.NET方案中實現它們。1.4節是本章最后一部分,簡要介紹一些設計方法學,以及運用本章中已經介紹的模式和原則的實踐。1.4 其他有名的設計實踐除了目前已經介紹的設計模式、原則和企業模式之外,我還想介紹幾種設計方法學:測試驅動開發、行為驅動開發及領域驅動開發。本節不會深入討論這些主題,因

25、為已超出了本書的范疇。但是,每一章用來演示模式和原則的關鍵示例代碼均是采用這些方法學設計的,可以從網站和上下載這些代碼。1.4.1 測試驅動設計TDD(Test-driven Development,測試驅動設計)并不像它的名稱所言,它更多的是一種設計方法學而不是測試策略,這個名稱只是不夠公正。這種設計方法學背后的主要思想是使用測試來塑造系統的設計。在創建軟件解決方案時,首先編寫一個導致測試失敗的測試程序來斷言某種業務邏輯。然后編寫代碼讓測試通過。最終,通過重構來清理所有代碼。這三步已經被人們稱為紅-綠-重構(red-green-refactor)。紅和綠指的是測試框架分別用來顯示測試通過和測

26、試失敗的顏色。通過經歷TDD流程,最終將得到一個帶有一套可以確認所有行為的測試的松耦合系統。TDD的一個副產品是這些測試提供了一種描述系統能夠做什么以及不能做什么的文檔。因為測試屬于系統的一部分,所以它絕不會過時,這與編寫的文檔和代碼注釋不同。更多有關TDD的信息請參考以下著作: Test Driven Development: By Example,Kent Beck著 The Art of Unit Testing: With Examples in .NET,Roy Osherove著 Professional Enterprise .NET,Jon Arking與Scott Mille

27、tt合著(Wrox出版)1.4.2 領域驅動設計簡而言之,DDD(Domain-driven Design,領域驅動設計)是一組有助于構建反映對業務的理解并滿足業務需求的應用程序的模式和原則。除此之外,它是一種思考開發方法學的全新方式。DDD的建模方式如下:首先通過全面理解真實領域來對真實領域建模,然后將所有的術語、規則和邏輯放到代碼的某種抽象表示中(通常是以領域模型的形式)。雖然DDD并不是一種框架,但是它確實有一組構建塊或概念可以整合到解決方案中。在第10章和第11章中構建案例研究應用程序時將運用這種方法學。在第4章中我們將更深入研究DDD的一些方面。有關DDD的更多信息,請參考以下著作: Domain-Driven Design: Tackling Complexity in the Heart of Software,Eric Evans著 Applying Domain-Driven Design and Patterns: With Examples in C# and .NET,Jimmy Nilsson著 .N

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論