個人設計模式總結

各位小牛大牛老鳥菜鳥們好,歡迎參觀個人設計模式世界。這個世界我已經總結多年了,如今纔剛剛成型。But I have a dream,夢想全部開發者都能一晚上之間認清全部設計模式,還幻想之後你們認識設計模式時,必首先google本文,嘿嘿。html

前輩同仁們已經總結過不少,至今首頁上設計模式的文章仍然層出不窮。但我總認爲,在GOF的23個設計模式提出多年了,該須要些變化和擴展了。特別適用於.NET(或Mono)的設計模式,好像沒有系統的總結。新年伊始,推出這篇總結,我我的不喜歡人云亦云,對設計模式的總體,以及其中一些模式,有獨特的理解,歡迎指點。程序員

引用阿彬同窗對術和道的論述在真正好的程序員心中,設計模式是「術」,設計模式背後的用意纔是「道」。爲何要用某個模式,是爲了解決什麼問題?緊耦合?可測性差?擴展性差?他們寫代碼時,心中已無設計模式,用心設計、簡單設計;在可測性、可擴展性和複雜程度之間作巧妙的權衡取捨;當他們寫完代碼,已經不知不覺合理地使用了若干設計模式。——其實我這句話也說錯了,代碼永遠沒有「寫完」的一天,他們會不斷重構它,重構出設計模式,或者重構掉設計模式。web

本文所列的設計模式基於維基百科,有些我認爲是魚目混珠,另外補充了幾個模式。我認識設計模式的方式有點不一樣,不想照搬一個模式的定義,更關心它的特徵,即長得像什麼,能作什麼,爲何要這樣作,這應該更方便新人理解。此外,還設法注意不一樣設計模式之間的聯繫。因爲時間篇幅關係,沒法貼出太多代碼,不過會指出多數模式在.NET BCL中的實現。面試

設計模式通常分爲建立、構造、行爲三類。我遵循這個分類,而作了一點調整,如Builder模式我放到構造分類中。 加上併發模式,共四類。併發類的模式稍後再補充。數據庫

除這個傳統的分類方式外,我會從另外三個角度爲設計模式歸納總結。編程

第一個角度就是語言的角度,本文主要基於C#/VB.NET(Mono)。設計模式並不是架構模式,它與語言特性緊密相關。很多模式在不一樣語言實現不一樣,好比單例模式。有些模式則是某種語言獨有的,好比RAII是C++專用模式。設計模式

第二個角度,是開發領域角度。編程開發可簡單分爲兩大領域,即框架開發和應用開發。明白這兩個領域的區別和聯繫,對理解設計模式的實現很是重要。在框架開發中,設計模式應用頻率要高得多,有些模式基本上只出現於框架中。作應用開發,常常會「應用」框架實現的設計模式,很多人用了而也稀裏糊塗地不知道。跨域

「應用」可能不算很確切的詞兒,仍是來個圖吧,表示一般狀況下,框架層和應用層合做的設計模式完整實現:緩存

image

我仍是先舉個最簡單的Entity Framework的例子吧,省得被鄙視。現在EF比較鍾情Code First,代碼以下:網絡

public class PersonMap      //這是對抽象的擴展
: EntityTypeConfiguration<Person>   //這是EF提供的抽象
{
    public PersonMap()
    {
        this.HasKey(p => p.IDCard);  //設IDCard爲主鍵屬性
    }
}

public class MyDbContext : DbContext
{
    public MyDbContext() : base("Entities") { }

    /// <summary>
    /// 在這個方法裏能作的事情,就是API
    /// </summary>
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {           
        modelBuilder.Configurations.Add(new PersonMap());  //這天然就是「應用」
    }

    public DbSet<Person> Persons { get; set; }
}

 

至於這是哪一種模式,但願把本文看完就明白了。

不是作應用開發就沒必要了解設計模式,偏偏相反,作應用開發由於接觸得少,更須要主動了解設計模式,以避免成日陷於業務海洋中成了磚家,專門搬磚蓋永遠蓋不到頂的業務大樓。並且有一些模式,應用開發中用的更頻繁。

無論是應用仍是建立完整的實現,均可以說使用了這個模式。面試官問你用過哪些模式的時候,隨便拾三兩個例子就行,別讓人家太崇拜你,嘿嘿。

咱們從上圖可見,設計模式實現分爲四部分。API和抽象能夠合算一部分,應該稱之「採用某設計模式的解決方案」,簡稱解決方案吧。然而不是全部模式的解決方案都須要抽象部分,沒有抽象天然也沒有擴展。根據設計模式是否提供擴展機制這點,能夠分爲擴展模式和非擴展模式,這就是第三個角度。可擴展的模式理解難度略大,不過也更有趣。

通常地講,構造模式都是可擴展的,行爲模式都是非擴展的,而建立模式兩者兼有。

1、建立模式 Creational patterns

1. 工廠方法模式 Factory Method

這個模式很簡單,就是不直接經過構造函數(用new關鍵字),而是經過調用某個方法(偶爾用屬性)獲得一個對象。好比WebRequest.Create(url)方法,返回HttpWebRequest對象。

爲何要用方法而不是new一個對象呢?三種緣由,一就是不想建立新的對象;二是建立新對象的邏輯比較複雜,複雜致使出錯建立失敗機率較高,而構造函數應該儘可能避免異常(疑似沿自C++的潛規則),因此習慣上推薦用方法建立,如Image類FromFile和FromHandle方法;三是爲了方便,好比 Stopwatch.StartNew()方法和Task.Factory.StartNew(action)方法。

下面許多其餘模式都會用工廠方法,由於咱們每每不知不覺就在用它,就不列舉了。這是一個最基礎最底層的模式。

靈活應用泛型可讓大大減小建立工廠方法的工做,如用Comparer<T>.Create(Comparion<T>)方法,不用寫不一樣類型的比較器類,就能建立出針對不一樣類型的比較器。

2. 抽象工廠模式 Abstract Factory

工廠就是指那種專門提供工廠方法的類。若是業務邏輯複雜起來,而若是想根據須要,分別獲得某一批而不是某一個類的實例,就須要有相應的一批工廠類。若是用抽象類或接口規定了這批工廠類的工廠方法,就是抽象工廠模式。通常來講,若工廠源自抽象工廠,其「產品」也繼承自某抽象類或接口。

此模式比上個複雜得多,但其實很好理解。曹操曾吟,對酒當歌,人生幾何。何以解憂,惟有杜康。他必定想不到現在還有拉菲產葡萄酒,茅臺產白酒,青啤產啤酒。若是曹公再世,粉絲想爲他寫個程序,就能夠定義一個抽象工廠:酒廠,拉菲等品牌繼承自酒廠,產品白酒啤酒都是酒,繼承自酒類。

上面提到的Task.Factory,是一個TaskFactory對象。像TaskFactory這種獨立工廠很少見,由於若只要獲得某個特定類的實例,一般像WebRequest/Image那樣在自身加一個靜態工廠方法便可。

這是個你們最熟悉的模式,被普遍應用在框架設計中,下表列了幾個BCL的例子。這種模式很好識別,由於工廠類名多帶Factory,和接口開頭的I,成了標準,不過也有一些深藏不露。

抽象工廠

工廠類

產品定義

產品類

IHttpHandlerFactory

PageHandlerFactory

IHttpHandler

Page, StaticFileHandler  等

IControllerFactory

DefaultControllerFactory

IController

Controller

DbProviderFactory

SqlDbFactory
OleDbFactory

DbCommand, DbDataAdapter 等

SqlCommand/OleDbCommand…
SqlDataAdapter/OleDbAdapter等

IEnumerable<T>

List<T>, HashSet<T>等

IEnumerator<T>

Listt`1+Enumerator<T>
HashSet`1+Enumerator<T> (編譯器實現)

IEnumerable<T>接口和List/HashSet,雖然不少人沒想到,倒是徹底標準的抽象工廠及實現。上個模式提到的Compare<T>,其實也是抽象工廠的變種實現,實現IComparer<T>的類,如 StringComparer/GenericComparer<T>,不是產生對象,而是對對象做處理統計,其實算另外一種設計模式,也能夠認爲是一個「工廠」。

傳統上,該模式還須要一個獲取具體工廠實例的工廠方法。在應用開發中,使用StructureMap等IoC框架能夠替代這種方法,甚至無須明確調用工廠類。

3. 延遲加載模式 Lazy initialization

這也是咱們不知不覺在用的模式。顧名思義,聲明某個屬性或變量時不當即初始化,直至用到才加載。這個模式用幾行代碼就能說明:

class ObjectWithLargeObjectProperty 
{ 
    LargeObject largeObjectField;

    public LargeObject LargeObject 
    { 
        get 
        {             
            if (largeObjectField == null) largeObjectField = new LargeObject(); //核心是該行 
            return largeObjectField; 
        } 
    } 
}

在用戶較多的應用系統中,要考慮併發的影響。應該儘可能採用Lazy<T>類(.NET 4.0+),能夠選擇併發時的建立對象策略。

4.單例模式 Singleton

讓一個類只能有一個實例,通常經過靜態屬性提供。這種類都是管理系統全局運行時信息,有時也能夠用靜態類代替,而用單例主要考慮擴展性和可測試性。 Comparer<T>.Default就是典型的單例模式。過去覺得像單例的是HttpContext.Current,只是一個像工廠的靜態屬性。

這種模式很常見。至於如何實現,首先必須讓構造函數變成私有的private。我看到許多例子用Lazy Initilization,還有雙重鎖,我的很不推薦。由於這種全局單例確定是系統運行必須且在通常系統啓動時就會初始化,因此簡單用靜態構造函數或靜態字段初始化便可,並保證併發性,就是Terry Lee的文章最後一種實現。

5.對象池模式 Object Pool

在應用開發中不多見,但框架開發中較多,由於使用該對象池的類通常涉及管理非託管資源。 想獲取某個類的實例,優先從池中取,若須要新建實例,也放入池中,用完後只是標誌其爲空閒狀態以備用。

ThreadPool類是一個擺明典型實現。還有DbConnection及其子類,使用鏈接池。在不是.NET,但息息相關的IIS中會用到ApplicationPool。

全部Object Pool都有一個大小限制。不管是實現仍是引用該模式,都要注意儘量地釋放池中對象。對於數據庫鏈接要合理關閉,對於Asp.NET能夠考慮用 IHttpAsnycHandler和IAsyncController(MVC)減小ApplicationPool的負載。

6. 享元模式 Fly Weight

以爲該模式相似對象池,都是爲了複用對象,多用於框架設計中。是一種建立模式,因此在放在這裏。區別一是該模式不會指定對象數量上限,二是保存共享對象的數據結構相似於字典,經過工廠方法傳遞過來的key,找到字典的既有對象,若沒找到則新建並存入字典中。

這是應用緩存的一種場景。若是有過時控制需求的話,能夠直接用MemoryCache類保存對象。

最典型的應用就是String類型。爲了節約內存,相同的字符串將指向相同的String實例(也有例外)。複用String的存儲器有個專用名字-拘留池,不過沒有數量大小限制。

7. 其餘

多例模式 Multition:應於單例,但從沒見過哪裏有標準的實現。一個類提供多個返回本身的靜態屬性倒很常見,如Color.Blue, Brushes.Red, 但不該該禁止別人建立新的實例。

原型模式 Prototype:把一個類實例當原型,經過複製建立新的實例。BCL中沒見過,而應用開發或許偶爾用一下不足以稱得上模式。由於通常像FlyWeight那樣引用到那個「原型」就能夠了。

Resource Acquisition Is Initialization:簡稱RAII。之前沒據說過,看代碼是C++中的模式。

 

構造模式 Structral Patterns

1. 組合模式 Composite

這種模式將某些對象由許多元件,按樹狀層級組合而成。應用很普遍,各類UI界面(Winform/WPF/Asp.Net Page),LINQ2XML,Lamda表達式等等,想必你們都很熟悉,很少做介紹了。

一樣該模式識別性也很高,甚至不管是否有開發經驗都能抽象出來,你們對樹狀結構太熟悉了。

可是該模式實現容易,卻有許多深刻的挑戰:要考慮樹狀結構如何最優雅地初始化,最簡捷明瞭地增刪改查。XLINQ這方面很是友好,值得借鑑,固然若是實現JQuery那種選擇器就更給力了。有的樹狀結構,好比地理信息,還要考慮如何存儲。

2.  建造者模式 Builder

傳統定義:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。

我的理解該模式作了擴展,傳統定義重點是要構建的複雜對象,我理解的該模式只應關注Builder「構建者」。只要符合這樣特徵:有一個定義幹Build流程,及組織這些流程的方式的抽象(類或接口),和將這個抽象各步流程具體實現的Builder類。

爲何必須擴展對Builder模式的理解呢,緣由有三:

1.應用設計模式是爲了在OCP原則下儘可能複用代碼,將不變的部分抽象,對可能變化的部分,提供封裝途徑。

2. 若是對象複雜到須要用Builder建立,不可能地每步都產生組件。必定會有許多處理過程,雖然不產生組件,但提供註冊,通信,驗證,測試,存檔等功能,這些過程也是能夠被抽象出來定義的,但傳統的Builder模式卻忽略了這些「無足輕重」的過程。

要麼那是一個理想化的模型,要麼或許現實中真有那種建立時根本無須和外界打交道的對象(對象越複雜,可能性越小)。多是我我的經驗太淺,還想象不到。

3. 既然須要在Builder中實現不產生組件的過程, 那麼漸漸地,若是生產「產品」佔整個業務比重變得很小甚至爲0, 顯然這仍然是Builder模式。

傳統認爲Builder必定要出「產品」,每一步產生「產品」的一個組件。然而,在抽象工廠模式中所述,工廠並不必定要有「產品」,只須包含加工處理邏輯。這裏的「產品」其實指編程語言能夠描述的對象,若是一個處理過程不出「產品」,並不表明沒有成果,可能在修改數據庫,操做文件,調用第三方API等等,這些事不能也沒必要描述爲「產品」對象。

3. 裝飾模式 Decorator

該械通常經過裝飾類的構造函數或工廠方法傳入待裝飾的對象,獲得增長了新功能的對象。 這個模式也很好理解,我以爲能夠和」適配器「合併。

經常使用的例子就是DeflateStream裝飾FileStream和MemoryStream。

.NET語言應該提供更好的支持,能夠容許複製一個對象的屬性到另外一個對象上,只要類型和名稱相同。

4. 適配器模式 Adapter/Wrapper/Translator

傳統定義的構造模式大都晦澀難懂,只有這個簡單,就是用現有的類型,再繼承一個接口,創造的新類型。爲了增長功能,這種作法再天然不過,算一個模式很勉強。

我想不出更好例子:不知道你們知不知道數據集,.NET2.0就有了,如今在VS中添加新項還能選它。它會鏈接一個數據庫,生成一些繼承DataTable 的實體類集合,就是AEF的DbSet<T>同樣,並實現IEnumerable<T>接口。

還有就是.NET 4.0,最經常使用的List<T>類如今實現兩個新接口: IReadOnlyList<T>和IReadonlyCollection<T>,這是爲了兼容WinRT。不過因爲新接口的內容已經包含在實現過的IList<T>和ICollection<T>中,只是作爲標記。

流行的名稱叫適配器模式,不過值得注意的是BCL中有兩個叫Adapter的類:ControlAdapter和DbDataAdapter,其實和該模式的沒任何關係。然而,我感受這兩個Adapter命名倒用得更恰當,但適配器更適合於下一個模式,叫Wrapper的話又容易和Decorator混淆,或許 Translator最好的名稱。ControlAdapter實際上是下面橋接模式的一個實現,DbDataAdapter則能夠算是服務模式。

一個對象若是要在List中排序,須實現IComparable接口,以適配.NET的潛規則。

5. 橋接模式 Bridge

原定義是:將抽象部分與實現部分分離,使它們均可以獨立的變化。說白了,就是老鼠吃大米大象吃樹葉,如今不是有轉基因了嗎,動物各器官都變成能夠嫁接的了。 把二者的胃分離出來,使之動態變化。 我認爲這種纔是真正的適配器模式。

正如上面的ControlAdapter,若是咱們在DataTable加入DbDataAdapter就徹底符合該模式。

其實這個模式,還隱含這樣一層意思,負責實現的這個Adapter,或者Handler,或者Operator,對象主要的業務邏輯都由其處理。否則也沒必要用這種方式,可能採用別的模式了,由於對象提供修改自身邏輯的擴展方式有許多種,下面模式會涉及到

6. 代理模式 Proxy

一看到Proxy這個詞,就想到用得最多就是經過VS工具自動生成的Service的代理類。還有一種狀況調用COM API,咱們得本身聲明一個代理方法,其實真能夠也由VS自動生成。對於NET來講,若是隻是調用本域的託管資源,無須此模式。

這個模式由兩部分組成:代理定義以及代理的實現機制。.NET優點是,對於應用開發,極少碰到在須要本身實現代理機制,常常咱們用了代理都沒以爲,好比跨域(AppDomain)調用。然而,咱們也要了解不一樣代理方式的特性,好比WCF只支持DataContract的類型傳輸。

我有個大膽的設想,既然WCF能夠整合各類網絡服務,甚至還有進程通信,不知道能不能推出一種代理框架,把COM,跨域,網絡的訪問所有整合。

7. 泛型模式

這是一種利用.NET對泛型的強大支持,使子類型的泛型成員無須強制轉換類型使用。 這很早就有人提出,我也有文章論述過。這是.NET獨有的模式,雖然有人說這是一種反模式,卻優雅又好用。

8. 其餘

門面模式 Facade: 我實在沒瞅出這怎麼算模式,哪裏抽象了不變,哪裏封裝了可變。

Front Controller:表示MVC或MVVM的架構模式,而非代碼層的設計模式。

3、行爲模式 Behavior Patterns

這類模式數量較多,因語言差別很大。下面列舉這些經常使用模式,可能還有很多漏掉的,歡迎補充。

1. 責任鏈模式 Chain of responsibility

以往對這個模式沒什麼印象,研究代碼後,感受描述了一個自動狀態機。

2. 解釋器模式 Interpreter

這個比較常見,我理解就是將一系列邏輯或一個對象的描述存儲在一個字符串中,例如ConnectionString格式化輸出。雖然增長了出錯的可能,好處嘛,就是一目瞭然,便於保存。像ConnectionString有工具幫忙生成,格式化輸出卻是比較糾結,用的時候每每要查。

3. 中介模式 Mediator

看定義,只要咱們項目的BL層根據Model,把業務封裝分爲不一樣的helper就是中介模式。這種模式是貧血實體設計的必然方案,雖然稱得上模式也很勉強,不過還有一些項目連這一點都作不到,好比會把全部業務代碼幾千幾萬行地塞進一個類裏。

我的觀察,中介者與橋接(適配器)區別是,後者業務實體內部含有適配器,前者沒有規定;還有前者應該負責對象所有的與外部交互,後者只負責一方面。

4. 命令模式 Command

意思就是用傳遞不一樣命令,改變系統的處理邏輯或策略,也能夠說包含了Strategy模式。狀態改變,策略改變的例子不少,這種命令在.NET中經常以枚舉形式出現,好比LoadOptions和SaveOptions(Linq to XML) ,SearchOptions(IO),還有ConflictMode和RefreshMode(EntityFramework),好像這種枚舉多以Options或Mode爲後綴。

5. 策略模式 Strategy & 狀態模式 State

爲何把這兩種模式一塊兒說呢,由於實在這兩種模式沒有本質區別,都是經過設置某個屬性,來改變一個類處理邏輯(靜態或實例都可)。但與命令模式不一樣的是,這兩種模式是靜態的,即在改變類邏輯後,之後全部的邏輯處理都遵循這次改變,直到再次改變。而命令模式是動態的,即在調用某方法時動態傳遞命令參數。每次調用之間命令參數沒必要相同,一次調用不影響下一次調用。

改變類邏輯的屬性,若是狀態模式,通常是枚舉,好比Control.ClientIDMode屬性;若是是策略模式,通常是委託或接口類型,好比Dictionary.Comparer屬性。不過在BCL中,通常這種策略只在構造函數中定義。

值得注意的是,在多數非.NET語言中,策略模式也包含動態調用。對於.NET,這種模式部分已被優雅的委託取代,好比Linq裏面許多方法,用處如此之廣以至稱不上一種模式了。沒有委託的C++,若要傳遞處理邏輯或方法,要麼經過指針(沒語法支持),要麼用此模式。Java既無委託又無指針,此模式成了生活必需品。

6. 規格模式 Specification

這種模式運用場合通常限於創建業務查詢條件,是種很是優雅的模式,老趙的文章有詳細論述。在我看來,算是Composite和Strategy模式的組合應用。對於非.NET來講,實現起來就沒那麼舒服了。

7. 空對象模式 Null object

提供一個默認的空對象,避免對null判斷,消除空引用異常,如String.Empty和Stream.Null。對於集合類,這麼作頗有意義,我以爲.NET能夠提供更好的語法支持。對於領域實體類,好像只是讓代碼變得更流暢(Fluent),應該還有發展潛力,參考當一個對象什麼也沒幹時

我發如今ORM中,Null-Object能起到很好的做用。在加載實體時,爲性能考慮咱們常不會加載其外鍵屬性實體,但現實中這些屬性是存在的,這就與代碼中讀取屬性一個光禿禿的null造成了矛盾。使用Null Object,是一個很好的妥協,防止業務邏輯變化時致使理解錯誤引發bug,參考上篇。

8. 銷燬模式 Dispose

這是.NET獨有的模式,目的是保證GC沒法回收的非託管資源,在利用完後獲得釋放。其方案是CLR要求咱們爲須要回收非託管資源的類,實現IDispose接口,實現方式要以下(摘自《.NET框架設計》):

public class ComplexResourceHandler : IDisposable
{
    IntPtr buffer;      //非託管內存指針
    SafeHandle resource;    //託管資源
    bool disposed;      //銷燬狀態

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (this.disposed) return;

        if (disposing)  //有條件釋放託管資源
        {
            resource.Dispose();
        }
        Marshal.FreeHGlobal(buffer);    //保證釋放非託管資源(簡化省略了判斷)
        disposed = true;
    }

    ~ComplexResourceHandler()
    {
        Dispose(false);
    }
}

這樣即便不使用using和try-finally語法,也能保證在GC回收對象時清理掉這些資源。 園子裏的鐵哥,應該常與之打交道。這些類從構造上說,其實符合適配模式。另外,按規範訪問已經dispose的對象,應該拋出ObjectDisposedException。這些搞得這個模式有點繁瑣無趣,.NET若是能增長更強力的語法特性就行了。

9. 試行模式 Try-Parse

對於.NET來講,在正常業務操做失敗時,拋出適當的異常是一種規範作法。雖然有一點性能負擔,但能使代碼更易維護。

然而某些狀況下對特別頻繁一些操做,則採用這種模式避免拋出異常而影響性能,將轉化結果傳遞給參數,將成功與否做返回值。 經常使用的如Int32.TryParse(string s, out int result)和Dictionary.TryGet(T key, out K value)。

對於不支持異常的如C語言等,這是最普通不過的作法了。能夠再次看出設計模式與語言特性息息相關。

10. 自選模式 Optional feature

這也是《.NET框架設計》提到的模式,中文名是我本身起的。主要用於框架開發。書上舉了Stream的例子,繼承Stream的類有許多,特性各異。有的可讀寫可定位,如MemoryStream,NetworkStream只讀,如HttpOutputStream只能寫。通常來講,設計模式都是儘量地將變化抽象出來。對於某些複雜業務的類如Stream,若是增長IRead/IWrite/ISeek,太多抽象會致使易用性下降,實際開發中又無API須要這些接口適配,且還沒法保證這些接口只被用於修飾Stream。因而就有這種模式,在一個類中爲所有業務操做提供可重寫的默認實現,並可查詢這些操做是否在子類中獲得支持。

能夠比較一下使用IRead接口和可選特性的調用方式:

static void Process(Stream stream, byte[] buffer)
{
    //使用IRead接口
    var readImp = stream as IRead;
    if (readImp != null)
    {
        var firstByte = readImp.Read(buffer, 0, buffer.Length);
    }

    //使用Optional feature
    if (stream.CanRead)
    {
        var firstByte = stream.Read(buffer, 0, buffer.Length);
    }
}

 

對於框架和應用總體系統而言,這是一種反模式。然而對應用開發而言,提升了易用性,下降了複雜性。注意到.NET4.5實現了支持async的一系列方法,這種模式更顯得方便。好比一個小超市,雖然購銷管理效率不及專門的菜市場和五金店,對於顧客卻很是便利。

其餘

服務者模式 Servant:例StringComparer。相似橋接模式中的橋,或者Adapter。跟中介者模式也很難區分。 

訪問者模式 Visitor: 這實際上是策略模式的動態變種。Visitor是業務邏輯類,操做共同的一類對象。不過在.NET中,如前所述,已經沒有什麼特別之處,也稱不上模式了。

迭代器模式 Iterator: 被foreach和yield取代

觀察者模式 Observer:已經被事件機制取代。

備忘錄模式 Memento:這雖然是一種不錯的解決方案,但是應用場合很稀有,好像沒太大意義記住。

模板方法 Template Method:只是面向對象繼承的基本特性。

 

把主要的設計模式一網打盡地籠統歸納了下,但願能幫助你們再也不困惑於.NET的設計模式,也但願你們能多提出意見。

相關文章
相關標籤/搜索