1. 程式人生 > >C#設計模式總結

C#設計模式總結

替代 version 論文 詞典 log 調用接口 常用 私有構造函數 額外

原文地址:http://www.cnblogs.com/zhili/p/SingletonPatterm.html

一、引言

  經過這段時間對設計模式的學習,自己的感觸還是很多的,因為我現在在寫代碼的時候,經常會想想這裏能不能用什麽設計模式來進行重構。所以,學完設計模式之後,感覺它會慢慢地影響到你寫代碼的思維方式。這裏對設計模式做一個總結,一來可以對所有設計模式進行一個梳理,二來可以做一個索引來幫助大家收藏。

  PS: 其實,很早之前我就看過所有的設計模式了,但是並沒有寫博客,但是不久就很快忘記了,也沒有起到什麽作用,這次以博客的形式總結出來,發現效果還是很明顯的,因為通過這種總結的方式,我對它理解更深刻了,也記住的更牢靠了,也影響了自己平時實現功能的思維。所以,我鼓勵大家可以通過做筆記的方式來把自己學到的東西進行梳理,這樣相信可以理解更深,更好,我也會一直寫下來,之後打算寫WCF一系列文章。

  其實WCF內容很早也看過了,並且博客園也有很多前輩寫的很好,但是,我覺得我還是需要自己總結,因為只有這樣,知識才是自己的,別人寫的多好,你看了之後,其實還是別人了,所以鼓勵大家幾點(對於這幾點,也是對自己的一個提醒):

  1. 要動手實戰別人博客中的例子;
  2. 實現之後進行總結,可以寫博客也可以自己記錄雲筆記等;
  3. 想想能不能進行擴展,進行舉一反三。

  系列導航:

  C#設計模式(1)——單例模式

C#設計模式(2)——簡單工廠模式

  C#設計模式(3)——工廠方法模式

  C#設計模式(4)——抽象工廠模式

  C#設計模式(5)——建造者模式(Builder Pattern)

  C#設計模式(6)——原型模式(Prototype Pattern)

  C#設計模式(7)——適配器模式(Adapter Pattern)

  C#設計模式(8)——橋接模式(Bridge Pattern)

  C#設計模式(9)——裝飾者模式(Decorator Pattern)

  C#設計模式(10)——組合模式(Composite Pattern)

  C#設計模式(11)——外觀模式(Facade Pattern)

  C#設計模式(12)——享元模式(Flyweight Pattern)

  C#設計模式(13)——代理模式(Proxy Pattern)

  C#設計模式(14)——模板方法模式(Template Method)

  C#設計模式(15)——命令模式(Command Pattern)

  C#設計模式(16)——叠代器模式(Iterator Pattern)

  C#設計模式(17)——觀察者模式(Observer Pattern)

  C#設計模式(18)——中介者模式(Mediator Pattern)

  C#設計模式(19)——狀態者模式(State Pattern)

  C#設計模式(20)——策略者模式(Stragety Pattern)

  C#設計模式(21)——責任鏈模式

  C#設計模式(22)——訪問者模式(Vistor Pattern)

  C#設計模式(23)——備忘錄模式(Memento Pattern)

二、 設計原則

  使用設計模式的根本原因是適應變化,提高代碼復用率,使軟件更具有可維護性和可擴展性。並且,在進行設計的時候,也需要遵循以下幾個原則:單一職責原則、開放封閉原則、裏氏代替原則、依賴倒置原則、接口隔離原則、合成復用原則和迪米特法則。下面就分別介紹了每種設計原則。

2.1 單一職責原則

  就一個類而言,應該只有一個引起它變化的原因。如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會影響到其他的職責,另外,把多個職責耦合在一起,也會影響復用性。

2.2 開閉原則(Open-Closed Principle)

  開閉原則即OCP(Open-Closed Principle縮寫)原則,該原則強調的是:一個軟件實體(指的類、函數、模塊等)應該對擴展開放,對修改關閉。即每次發生變化時,要通過添加新的代碼來增強現有類型的行為,而不是修改原有的代碼。

  符合開閉原則的最好方式是提供一個固有的接口,然後讓所有可能發生變化的類實現該接口,讓固定的接口與相關對象進行交互。

2.3 裏氏代替原則(Liskov Substitution Principle)

  Liskov Substitution Principle,LSP(裏氏代替原則)指的是子類必須替換掉它們的父類型。也就是說,在軟件開發過程中,子類替換父類後,程序的行為是一樣的。只有當子類替換掉父類後,此時軟件的功能不受影響時,父類才能真正地被復用,而子類也可以在父類的基礎上添加新的行為。為了就來看看違反了LSP原則的例子,具體代碼如下所示:

 public class Rectangle
    {
        public virtual long Width { get; set; }
        public virtual long Height { get; set; }
    }
    // 正方形
    public class Square : Rectangle
    {
        public override long Height
        {
            get
            {
                return base.Height;
            }
            set
            {
                base.Height = value;
                base.Width = value;
            }
        }

        public override long Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
                base.Height = value;
            }
        }
    }
 class Test
    {
        public void Resize(Rectangle r)
        {
            while (r.Height >= r.Width)
            {
                r.Width += 1;
            }
        }
        var r = new Square() { Width = 10, Height = 10 };
         new Test().Resize(r);
     }

  上面的設計,正如上面註釋的一樣,在執行SmartTest的resize方法時,如果傳入的是長方形對象,當高度大於寬度時,會自動增加寬度直到超出高度。但是如果傳入的是正方形對象,則會陷入死循環。此時根本原因是,矩形不能作為正方形的父類,既然出現了問題,可以進行重構,使它們倆都繼承於四邊形類。重構後的代碼如下所示:

 // 四邊形
    public abstract class Quadrangle
    {
        public virtual long Width { get; set; }
        public virtual long Height { get; set; }
    }
    // 矩形
    public class Rectangle : Quadrangle
    {
        public override long Height { get; set; }

        public override long Width { get; set; }
       
    }
    // 正方形
    public class Square : Quadrangle
    {
        public long _side;

        public Square(long side)
        {
            _side = side;
        }
    }
 class Test
    {
        public void Resize(Quadrangle r)
        {
            while (r.Height >= r.Width)
            {
                r.Width += 1;
            }
        }


        static void Main(string[] args)
        {
            var s = new Square(10);

            new Test().Resize(s);
        }
    }

2.4 依賴倒置原則

  依賴倒置(Dependence Inversion Principle, DIP)原則指的是抽象不應該依賴於細節,細節應該依賴於抽象,也就是提出的 “面向接口編程,而不是面向實現編程”。這樣可以降低客戶與具體實現的耦合。

2.5 接口隔離原則

  接口隔離原則(Interface Segregation Principle, ISP)指的是使用多個專門的接口比使用單一的總接口要好。也就是說不要讓一個單一的接口承擔過多的職責,而應把每個職責分離到多個專門的接口中,進行接口分離。過於臃腫的接口是對接口的一種汙染。

2.6 合成復用原則

  合成復用原則(Composite Reuse Principle, CRP)就是在一個新的對象裏面使用一些已有的對象,使之成為新對象的一部分。新對象通過向這些對象的委派達到復用已用功能的目的。簡單地說,就是要盡量使用合成/聚合,盡量不要使用繼承。

  要使用好合成復用原則,首先需要區分"Has—A"和“Is—A”的關系。

  “Is—A”是指一個類是另一個類的“一種”,是屬於的關系,而“Has—A”則不同,它表示某一個角色具有某一項責任。導致錯誤的使用繼承而不是聚合的常見的原因是錯誤地把“Has—A”當成“Is—A”.例如:

技術分享

實際上,雇員、經歷、學生描述的是一種角色,比如一個人是“經理”必然是“雇員”。在上面的設計中,一個人無法同時擁有多個角色,是“雇員”就不能再是“學生”了,這顯然不合理,因為現在很多在職研究生,即使雇員也是學生。

  上面的設計的錯誤源於把“角色”的等級結構與“人”的等級結構混淆起來了,誤把“Has—A”當作"Is—A"。具體的解決方法就是抽象出一個角色類:

技術分享

2.7 迪米特法則

  迪米特法則(Law of Demeter,LoD)又叫最少知識原則(Least Knowledge Principle,LKP),指的是一個對象應當對其他對象有盡可能少的了解。也就是說,一個模塊或對象應盡量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立,這樣當一個模塊修改時,影響的模塊就會越少,擴展起來更加容易。

  關於迪米特法則其他的一些表述有:只與你直接的朋友們通信;不要跟“陌生人”說話。

  外觀模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法則。

三、創建型模式

  創建型模式就是用來創建對象的模式,抽象了實例化的過程。所有的創建型模式都有兩個共同點。第一,它們都將系統使用哪些具體類的信息封裝起來;第二,它們隱藏了這些類的實例是如何被創建和組織的。創建型模式包括單例模式、工廠方法模式、抽象工廠模式、建造者模式和原型模式。

  • 單例模式:解決的是實例化對象的個數的問題,比如抽象工廠中的工廠、對象池等,除了Singleton之外,其他創建型模式解決的都是 new 所帶來的耦合關系。
  • 抽象工廠:創建一系列相互依賴對象,並能在運行時改變系列。
  • 工廠方法:創建單個對象,在Abstract Factory有使用到。
  • 原型模式:通過拷貝原型來創建新的對象。

  工廠方法,抽象工廠, 建造者都需要一個額外的工廠類來負責實例化“一個對象”,而Prototype則是通過原型(一個特殊的工廠類)來克隆“易變對象”。

  下面詳細介紹下它們。

3.1 單例模式

  單例模式指的是確保某一個類只有一個實例,並提供一個全局訪問點。解決的是實體對象個數的問題,而其他的建造者模式都是解決new所帶來的耦合關系問題。其實現要點有:

  • 類只有一個實例。問:如何保證呢?答:通過私有構造函數來保證類外部不能對類進行實例化
  • 提供一個全局的訪問點。問:如何實現呢?答:創建一個返回該類對象的靜態方法

  單例模式的結構圖如下所示:

技術分享

3.2 工廠方法模式

  工廠方法模式指的是定義一個創建對象的工廠接口,由其子類決定要實例化的類,將實際創建工作推遲到子類中。它強調的是”單個對象“的變化。其實現要點有:

  • 定義一個工廠接口。問:如何實現呢?答:聲明一個工廠抽象類
  • 由其具體子類創建對象。問:如何去實現呢?答:創建派生於工廠抽象類,即由具體工廠去創建具體產品,既然要創建產品,自然需要產品抽象類和具體產品類了。

  其具體的UML結構圖如下所示:

技術分享

  在工廠方法模式中,工廠類與具體產品類具有平行的等級結構,它們之間是一一對應關系。

3.3 抽象工廠模式

  抽象工廠模式指的是提供一個創建一系列相關或相互依賴對象的接口,使得客戶端可以在不必指定產品的具體類型的情況下,創建多個產品族中的產品對象,強調的是”系列對象“的變化。其實現要點有:

  • 提供一系列對象的接口。問:如何去實現呢?答:提供多個產品的抽象接口
  • 創建多個產品族中的多個產品對象。問:如何做到呢?答:每個具體工廠創建一個產品族中的多個產品對象,多個具體工廠就可以創建多個產品族中的多個對象了。

  具體的UML結構圖如下所示:

  技術分享

3.4 建造者模式

  建造者模式指的是將一個產品的內部表示與產品的構造過程分割開來,從而可以使一個建造過程生成具體不同的內部表示的產品對象。強調的是產品的構造過程。其實現要點有:

  • 將產品的內部表示與產品的構造過程分割開來。問:如何把它們分割開呢?答:不要把產品的構造過程放在產品類中,而是由建造者類來負責構造過程,產品的內部表示放在產品類中,這樣不就分割開了嘛。

  具體的UML結構圖如下所示:

技術分享  

3.5 原型工廠模式

  原型模式指的是通過給出一個原型對象來指明所要創建的對象類型,然後用復制的方法來創建出更多的同類型對象。其實現要點有:

  • 給出一個原型對象。問:如何辦到呢?答:很簡單嘛,直接給出一個原型類就好了。
  • 通過復制的方法來創建同類型對象。問:又是如何實現呢?答:.NET可以直接調用MemberwiseClone方法來實現淺拷貝

  具體的UML結構圖如下所示:

技術分享

四、結構型模式

  結構型模式,顧名思義討論的是類和對象的結構 ,主要用來處理類或對象的組合。它包括兩種類型,一是類結構型模式,指的是采用繼承機制來組合接口或實現;二是對象結構型模式,指的是通過組合對象的方式來實現新的功能。它包括適配器模式、橋接模式、裝飾者模式、組合模式、外觀模式、享元模式和代理模式。

  • 適配器模式註重轉換接口,將不吻合的接口適配對接
  • 橋接模式註重分離接口與其實現,支持多維度變化
  • 組合模式註重統一接口,將“一對多”的關系轉化為“一對一”的關系
  • 裝飾者模式註重穩定接口,在此前提下為對象擴展功能
  • 外觀模式註重簡化接口,簡化組件系統與外部客戶程序的依賴關系
  • 享元模式註重保留接口,在內部使用共享技術對對象存儲進行優化
  • 代理模式註重假借接口,增加間接層來實現靈活控制

4.1 適配器模式

  適配器模式意在轉換接口,它能夠使原本不能再一起工作的兩個類一起工作,所以經常用來在類庫的復用、代碼遷移等方面。例如DataAdapter類就應用了適配器模式。適配器模式包括類適配器模式和對象適配器模式,具體結構如下圖所示,左邊是類適配器模式,右邊是對象適配器模式。

技術分享

4.2 橋接模式

  橋接模式旨在將抽象化與實現化解耦,使得兩者可以獨立地變化。意思就是說,橋接模式把原來基類的實現化細節再進一步進行抽象,構造到一個實現化的結構中,然後再把原來的基類改造成一個抽象化的等級結構,這樣就可以實現系統在多個維度的獨立變化,橋接模式的結構圖如下所示。

技術分享

4.3 裝飾者模式

  裝飾者模式又稱包裝(Wrapper)模式,它可以動態地給一個對象添加一些額外的功能,裝飾者模式較繼承生成子類的方式更加靈活。雖然裝飾者模式能夠動態地將職責附加到對象上,但它也會造成產生一些細小的對象,增加了系統的復雜度。具體的結構圖如下所示。

技術分享

4.4 組合模式

  組合模式又稱為部分—整體模式。組合模式將對象組合成樹形結構,用來表示整體與部分的關系。組合模式使得客戶端將單個對象和組合對象同等對待。如在.NET中WinForm中的控件,TextBox、Label等簡單控件繼承與Control類,同時GroupBox這樣的組合控件也是繼承於Control類。組合模式的具體結構圖如下所示。

技術分享

4.5 外觀模式

  在系統中,客戶端經常需要與多個子系統進行交互,這樣導致客戶端會隨著子系統的變化而變化,此時可以使用外觀模式把客戶端與各個子系統解耦。外觀模式指的是為子系統中的一組接口提供一個一致的門面,它提供了一個高層接口,這個接口使子系統更加容易使用。如電信的客戶專員,你可以讓客戶專員來完成沖話費,修改套餐等業務,而不需要自己去與各個子系統進行交互。具體類結構圖如下所示:

技術分享

4.6 享元模式

  在系統中,如何我們需要重復使用某個對象時,此時如果重復地使用new操作符來創建這個對象的話,這對系統資源是一個極大的浪費,既然每次使用的都是同一個對象,為什麽不能對其共享呢?這也是享元模式出現的原因。

  享元模式運用共享的技術有效地支持細粒度的對象,使其進行共享。在.NET類庫中,String類的實現就使用了享元模式,String類采用字符串駐留池的來使字符串進行共享。更多內容參考博文:http://www.cnblogs.com/artech/archive/2010/11/25/internedstring.html。享元模式的具體結構圖如下所示。

技術分享

4.7 代理模式

  在系統開發中,有些對象由於網絡或其他的障礙,以至於不能直接對其訪問,此時可以通過一個代理對象來實現對目標對象的訪問。如.NET中的調用Web服務等操作。

  代理模式指的是給某一個對象提供一個代理,並由代理對象控制對原對象的訪問。具體的結構圖如下所示。

  技術分享

  註:外觀模式、適配器模式和代理模式區別?

  解答:這三個模式的相同之處是,它們都是作為客戶端與真實被使用的類或系統之間的一個中間層,起到讓客戶端間接調用真實類的作用,不同之處在於,所應用的場合和意圖不同。

  代理模式與外觀模式主要區別在於,代理對象無法直接訪問對象,只能由代理對象提供訪問,而外觀對象提供對各個子系統簡化訪問調用接口,而適配器模式則不需要虛構一個代理者,目的是復用原有的接口。外觀模式是定義新的接口,而適配器則是復用一個原有的接口。

  另外,它們應用設計的不同階段,外觀模式用於設計的前期,因為系統需要前期就需要依賴於外觀,而適配器應用於設計完成之後,當發現設計完成的類無法協同工作時,可以采用適配器模式。然而很多情況下在設計初期就要考慮適配器模式的使用,如涉及到大量第三方應用接口的情況;代理模式是模式完成後,想以服務的方式提供給其他客戶端進行調用,此時其他客戶端可以使用代理模式來對模塊進行訪問。

  總之,代理模式提供與真實類一致的接口,旨在用來代理類來訪問真實的類,外觀模式旨在簡化接口,適配器模式旨在轉換接口。

五、行為型模式

  行為型模式是對在不同對象之間劃分責任和算法的抽象化。行為模式不僅僅關於類和對象,還關於它們之間的相互作用。行為型模式又分為類的行為模式和對象的行為模式兩種。

  • 類的行為模式——使用繼承關系在幾個類之間分配行為。
  • 對象的行為模式——使用對象聚合的方式來分配行為。

  行為型模式包括11種模式:模板方法模式、命令模式、叠代器模式、觀察者模式、中介者模式、狀態模式、策略模式、責任鏈模式、訪問者模式、解釋器模式和備忘錄模式。

  • 模板方法模式:封裝算法結構,定義算法骨架,支持算法子步驟變化。
  • 命令模式:註重將請求封裝為對象,支持請求的變化,通過將一組行為抽象為對象,實現行為請求者和行為實現者之間的解耦。
  • 叠代器模式:註重封裝特定領域變化,支持集合的變化,屏蔽集合對象內部復雜結構,提供客戶程序對它的透明遍歷。
  • 觀察者模式:註重封裝對象通知,支持通信對象的變化,實現對象狀態改變,通知依賴它的對象並更新。
  • 中介者模式:註重封裝對象間的交互,通過封裝一系列對象之間的復雜交互,使他們不需要顯式相互引用,實現解耦。
  • 狀態模式:註重封裝與狀態相關的行為,支持狀態的變化,通過封裝對象狀態,從而在其內部狀態改變時改變它的行為。
  • 策略模式:註重封裝算法,支持算法的變化,通過封裝一系列算法,從而可以隨時獨立於客戶替換算法。
  • 責任鏈模式:註重封裝對象責任,支持責任的變化,通過動態構建職責鏈,實現事務處理。
  • 訪問者模式:註重封裝對象操作變化,支持在運行時為類結構添加新的操作,在類層次結構中,在不改變各類的前提下定義作用於這些類實例的新的操作。
  • 備忘錄模式:註重封裝對象狀態變化,支持狀態保存、恢復。
  • 解釋器模式:註重封裝特定領域變化,支持領域問題的頻繁變化,將特定領域的問題表達為某種語法規則下的句子,然後構建一個解釋器來解釋這樣的句子,從而達到解決問題的目的。

5.1 模板方法模式

  在現實生活中,有論文模板,簡歷模板等。在現實生活中,模板的概念是給定一定的格式,然後其他所有使用模板的人可以根據自己的需求去實現它。同樣,模板方法也是這樣的。

  模板方法模式是在一個抽象類中定義一個操作中的算法骨架,而將一些具體步驟實現延遲到子類中去實現。模板方法使得子類可以不改變算法結構的前提下,重新定義算法的特定步驟,從而達到復用代碼的效果。具體的結構圖如下所示。

技術分享

以生活中做菜為例子實現的模板方法結構圖

5.2 命令模式

  命令模式屬於對象的行為模式,命令模式把一個請求或操作封裝到一個對象中,通過對命令的抽象化來使得發出命令的責任和執行命令的責任分隔開。命令模式的實現可以提供命令的撤銷和恢復功能。具體的結構圖如下所示。

技術分享

5.3 叠代器模式

  叠代器模式是針對集合對象而生的,對於集合對象而言,必然涉及到集合元素的添加刪除操作,也肯定支持遍歷集合元素的操作,此時如果把遍歷操作也放在集合對象的話,集合對象就承擔太多的責任了,此時可以進行責任分離,把集合的遍歷放在另一個對象中,這個對象就是叠代器對象。

  叠代器模式提供了一種方法來順序訪問一個集合對象中各個元素,而又無需暴露該對象的內部表示,這樣既可以做到不暴露集合的內部結構,又可以讓外部代碼透明地訪問集合內部元素。具體的結構圖如下所示。

技術分享

5.4 觀察者模式

  在現實生活中,處處可見觀察者模式,例如,微信中的訂閱號,訂閱博客和QQ微博中關註好友,這些都屬於觀察者模式的應用。

  觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己的行為。具體結構圖如下所示:

技術分享

5.5 中介者模式

  在現實生活中,有很多中介者模式的身影,例如QQ遊戲平臺,聊天室、QQ群和短信平臺,這些都是中介者模式在現實生活中的應用。

  中介者模式,定義了一個中介對象來封裝一系列對象之間的交互關系。中介者使各個對象之間不需要顯式地相互引用,從而使耦合性降低,而且可以獨立地改變它們之間的交互行為。具體的結構圖如下所示:

技術分享

5.6 狀態模式

  每個對象都有其對應的狀態,而每個狀態又對應一些相應的行為,如果某個對象有多個狀態時,那麽就會對應很多的行為。那麽對這些狀態的判斷和根據狀態完成的行為,就會導致多重條件語句,並且如果添加一種新的狀態時,需要更改之前現有的代碼。這樣的設計顯然違背了開閉原則,狀態模式正是用來解決這樣的問題的。

  狀態模式——允許一個對象在其內部狀態改變時自動改變其行為,對象看起來就像是改變了它的類。具體的結構圖如下所示:

技術分享

5.7 策略模式

  在現實生活中,中國的所得稅,分為企業所得稅、外商投資企業或外商企業所得稅和個人所得稅,針對於這3種所得稅,每種所計算的方式不同,個人所得稅有個人所得稅的計算方式,而企業所得稅有其對應計算方式。如果不采用策略模式來實現這樣一個需求的話,我們會定義一個所得稅類,該類有一個屬性來標識所得稅的類型,並且有一個計算稅收的CalculateTax()方法,在該方法體內需要對稅收類型進行判斷,通過if-else語句來針對不同的稅收類型來計算其所得稅。這樣的實現確實可以解決這個場景,但是這樣的設計不利於擴展,如果系統後期需要增加一種所得稅時,此時不得不回去修改CalculateTax方法來多添加一個判斷語句,這樣明白違背了“開放——封閉”原則。此時,我們可以考慮使用策略模式來解決這個問題,既然稅收方法是這個場景中的變化部分,此時自然可以想到對稅收方法進行抽象,這也是策略模式實現的精髓所在。

  策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開,委派給不同的對象負責。策略模式通常把一系列的算法包裝到一系列的策略類裏面。用一句話慨括策略模式就是——“將每個算法封裝到不同的策略類中,使得它們可以互換”。下面是策略模式的結構圖:

  技術分享

5.8 責任鏈模式

  在現實生活中,有很多請求並不是一個人說了就算的,例如面試時的工資,低於1萬的薪水可能技術經理就可以決定了,但是1萬~1萬5的薪水可能技術經理就沒這個權利批準,可能需要請求技術總監的批準。

  責任鏈模式——某個請求需要多個對象進行處理,從而避免請求的發送者和接收之間的耦合關系。將這些對象連成一條鏈子,並沿著這條鏈子傳遞該請求,直到有對象處理它為止。具體結構圖如下所示:

技術分享

5.9 訪問者模式

  訪問者模式是封裝一些施加於某種數據結構之上的操作。一旦這些操作需要修改的話,接受這個操作的數據結構則可以保存不變。訪問者模式適用於數據結構相對穩定的系統, 它把數據結構和作用於數據結構之上的操作之間的耦合度降低,使得操作集合可以相對自由地改變。具體結構圖如下所示:

技術分享

5.10 備忘錄模式

  生活中的手機通訊錄備忘錄,操作系統備份點,數據庫備份等都是備忘錄模式的應用。備忘錄模式是在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣以後就可以把該對象恢復到原先的狀態。具體的結構圖如下所示:

技術分享

5.11 解釋器模式

  解釋器模式是一個比較少用的模式,所以我自己也沒有對該模式進行深入研究,在生活中,英漢詞典的作用就是實現英文和中文互譯,這就是解釋器模式的應用。

  解釋器模式是給定一種語言,定義它文法的一種表示,並定義一種解釋器,這個解釋器使用該表示來解釋器語言中的句子。具體的結構圖如下所示:

技術分享

六、總結

  23種設計模式,其實前輩們總結出來解決問題的方式,它們追求的宗旨還是保證系統的低耦合高內聚,指導它們的原則無非就是封裝變化,責任單一,面向接口編程等設計原則。之後,我會繼續分享自己WCF的學習過程,盡管博客園中有很多WCF系列,之前覺得沒必要寫,覺得會用就行了,但是不寫,總感覺知識不是自己的,感覺沒有深入,所以還是想寫這樣一個系列,希望各位博友後面多多支持。

  PS: 很多論壇都看到初學者問,WCF現在還有沒有必要深入學之類的問題,因為他們覺得這些技術可能會過時,說不定到時候微軟又推出了一個新的SOA的實現方案了,那豈不是白花時間深入學了,所以就覺得沒必要深入去學,知道用就可以了。對於這個問題,我之前也有這樣同樣的感覺,但是現在我覺得,盡管WCF技術可能會被替換,但深入了解一門技術,重點不是知道一些更高深API的調用啊,而是了解它的實現機制和思維方式,即使後面這個技術被替代了,其背後機制也肯定是相似的。所以深入了解了一個技術,你就會感覺新的技術熟悉,對其感覺放松。並且,你深入了解完一門技術之後,你面試時也敢說你很好掌握了這門技術,而不至於說平時使用的很多,一旦深入問時卻不知道背後實現原理。這也是我要寫WCF系列的原因。希望這點意見對一些初學者有幫助。

  

C#設計模式總結