C#設計模式總結

  1、 設計原則html

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

  1.1 單一職責原則算法

  就一個類而言,應該只有一個引發它變化的緣由。若是一個類承擔的職責過多,就等於把這些職責耦合在一塊兒,一個職責的變化可能會影響到其餘的職責。另外,把多個職責耦合在一塊兒,也會影響複用性。數據庫

  1.2 開閉原則(Open-Closed Principle)編程

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

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

  1.3 里氏代替原則(Liskov Substitution Principle)網絡

  Liskov Substitution Principle,LSP(里氏代替原則)指的是子類必須替換掉它們的父類型。也就是說,在軟件開發過程當中,子類替換父類後,程序的行爲是同樣的。只有當子類替換掉父類後,此時軟件的功能不受影響時,父類才能真正地被複用,而子類也能夠在父類的基礎上添加新的行爲。數據結構

  1.4 依賴倒置原則app

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

  1.5 接口隔離原則

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

  1.6 合成複用原則

  合成複用原則(Composite Reuse Principle, CRP)就是在一個新的對象裏面使用一些已有的對象,使之成爲新對象的一部分。新對象經過向這些對象的委派達到複用已用功能的目的。簡單地說,就是要儘可能使用合成/聚合,儘可能不要使用繼承。
  要使用好合成複用原則,首先須要區分"Has—A"和「Is—A」的關係:

  1)「Is—A」是指一個類是另外一個類的「一種」,是屬於的關係;

  2)而「Has—A」則不一樣,它表示某一個角色具備某一項責任。

  致使錯誤的使用繼承而不是聚合的常見的緣由是錯誤地把「Has—A」當成「Is—A」。例如:

  

  實際上,僱員、經理、學生描述的是一種角色。好比,一我的是「經理」必然是「僱員」。在上面的設計中,一我的沒法同時擁有多個角色,是「僱員」就不能再是「學生」了,這顯然不合理,由於如今不少在職研究生,即便僱員也是學生。
  上面的設計的錯誤源於把「角色」的等級結構與「人」的等級結構混淆起來了,誤把「Has—A」看成"Is—A"。具體的解決方法就是抽象出一個角色類:

  

  1.7 迪米特法則

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

  關於迪米特法則其餘的一些表述有:只與你直接的朋友們通訊,不要跟「陌生人」說話。

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

  2、建立型模式

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

  單例模式:解決的是實例化對象的個數的問題,好比抽象工廠中的工廠、對象池等。除了Singleton以外,其餘建立型模式解決的都是 new 所帶來的耦合關係。

  抽象工廠:建立一系列相互依賴對象,並能在運行時改變系列。

  工廠方法:建立單個對象,在Abstract Factory有使用到。

  原型模式:經過拷貝原型來建立新的對象。

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

  下面詳細介紹下它們。

  2.1  單例模式

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

  類只有一個實例。問:如何保證呢?答:經過私有構造函數來保證類外部不能對類進行實例化。

  提供一個全局的訪問點。問:如何實現呢?答:建立一個返回該類對象的靜態方法。

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

  
  2.2 工廠方法模式

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

  定義一個工廠接口。問:如何實現呢?答:聲明一個工廠抽象類。

  由其具體子類建立對象。問:如何去實現呢?答:建立派生於工廠抽象類,即由具體工廠去建立具體產品,既然要建立產品,天然須要產品抽象類和具體產品類了。

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

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

  2.3 抽象工廠模式

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

  提供一系列對象的接口。問:如何去實現呢?答:提供多個產品的抽象接口。

  建立多個產品族中的多個產品對象。問:如何作到呢?答:每一個具體工廠建立一個產品族中的多個產品對象,多個具體工廠就能夠建立多個產品族中的多個對象了。

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

  
  2.4 建造者模式

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

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

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

  
  2.5 原型工廠模式

  原型模式指的是經過給出一個原型對象來指明所要建立的對象類型,而後用複製的方法來建立出更多的同類型對象。其實現要點有:

  給出一個原型對象。問:如何辦到呢?答:很簡單嘛,直接給出一個原型類就行了。

  經過複製的方法來建立同類型對象。問:又是如何實現呢?答:.NET能夠直接調用MemberwiseClone方法來實現淺拷貝。

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

  3、結構型模式

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

  適配器模式:注重轉換接口,將不吻合的接口適配對接。

  橋接模式注重分離接口與其實現,支持多維度變化

  組合模式注重統一接口,將「一對多」的關係轉化爲「一對一」的關係

  裝飾者模式注重穩定接口,在此前提下爲對象擴展功能

  外觀模式注重簡化接口,簡化組件系統與外部客戶程序的依賴關係

  享元模式注重保留接口,在內部使用共享技術對對象存儲進行優化

  代理模式注重假借接口,增長間接層來實現靈活控制

  3.1 適配器模式

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

  

  3.2 橋接模式

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

  

  3.3 裝飾者模式

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

  

  3.4 組合模式

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

  
  3.5 外觀模式

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

  

  3.6 享元模式

  在系統中,若是咱們須要重複使用某個對象時。此時,若是重複地使用new操做符來建立這個對象的話,這對系統資源是一個極大的浪費,既然每次使用的都是同一個對象,爲何不能對其共享呢?這也是享元模式出現的緣由。

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

  

  3.7 代理模式

  在系統開發中,有些對象因爲網絡或其餘的障礙,以致於不能直接對其訪問。此時能夠經過一個代理對象來實現對目標對象的訪問。如.NET中的調用Web服務等操做。

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

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

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

  代理模式與外觀模式主要區別在於:

  1)客戶對象沒法直接訪問對象,只能由代理對象提供訪問。

  2)而外觀對象提供對各個子系統簡化訪問調用接口。

  而適配器模式則不須要虛構一個代理者,目的是複用原有的接口。

  外觀模式是定義新的接口,而適配器則是複用一個原有的接口。

  另外,它們應用設計的不一樣階段。外觀模式用於設計的前期,由於系統須要前期就須要依賴於外觀。而適配器應用於設計完成以後,當發現設計完成的類沒法協同工做時,能夠採用適配器模式。然而,不少狀況下在設計初期就要考慮適配器模式的使用,如涉及到大量第三方應用接口的狀況;代理模式是設計完成後,想以服務的方式提供給其餘客戶端進行調用,此時其餘客戶端可使用代理模式來對模塊進行訪問。

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

  4、行爲型模式

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

  類的行爲模式——使用繼承關係在幾個類之間分配行爲。

  對象的行爲模式——使用對象聚合的方式來分配行爲。

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

  模板方法模式:封裝算法結構,定義算法骨架,支持算法子步驟變化。

  命令模式:注重將請求封裝爲對象,支持請求的變化,經過將一組行爲抽象爲對象,實現行爲請求者和行爲實現者之間的解耦。

  迭代器模式:注重封裝特定領域變化,支持集合的變化,屏蔽集合對象內部複雜結構,提供客戶程序對它的透明遍歷。

  觀察者模式:注重封裝對象通知,支持通訊對象的變化,實現對象狀態改變,通知依賴它的對象並更新。

  中介者模式:注重封裝對象間的交互,經過封裝一系列對象之間的複雜交互,使他們不須要顯式相互引用,實現解耦。

  狀態模式:注重封裝與狀態相關的行爲,支持狀態的變化,經過封裝對象狀態,從而在其內部狀態改變時改變它的行爲。

  策略模式:注重封裝算法,支持算法的變化,經過封裝一系列算法,從而能夠隨時獨立於客戶替換算法。

  責任鏈模式:注重封裝對象責任,支持責任的變化,經過動態構建職責鏈,實現事務處理。

  訪問者模式:注重封裝對象操做變化,支持在運行時爲類結構添加新的操做,在類層次結構中,在不改變各種的前提下定義做用於這些類實例的新的操做。

  備忘錄模式:注重封裝對象狀態變化,支持狀態保存、恢復。

  解釋器模式:注重封裝特定領域變化,支持領域問題的頻繁變化,將特定領域的問題表達爲某種語法規則下的句子,而後構建一個解釋器來解釋這樣的句子,從而達到解決問題的目的。

  4.1 模板方法模式

  在現實生活中,有論文模板,簡歷模板等。在現實生活中,模板的概念是給定必定的格式,而後其餘全部使用模板的人能夠根據本身的需求去實現它。一樣,模板方法也是這樣的。

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

  

  4.2 命令模式

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

  
  4.3 迭代器模式

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

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

  
  4.4 觀察者模式

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

  觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身的行爲。具體結構圖以下所示:

  
  4.5 中介者模式

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

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

  
  4.6 狀態模式

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

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

  
  4.7 策略模式

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

  策略模式是對算法的包裝,是把使用算法的責任和算法自己分割開,委派給不一樣的對象負責。策略模式一般把一系列的算法包裝到一系列的策略類裏面。用一句話慨括策略模式就是——「將每一個算法封裝到不一樣的策略類中,使得它們能夠互換」。下面是策略模式的結構圖: 

  
  4.8 責任鏈模式

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

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

  
  4.9 訪問者模式

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

  
  4.10 備忘錄模式

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

  
  4.11 解釋器模式

  解釋器模式是一個比較少用的模式,因此我本身也沒有對該模式進行深刻研究。在生活中,英漢詞典的做用就是實現英文和中文互譯,這就是解釋器模式的應用。

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

  

  5、總結

  23種設計模式,是前輩們總結出來解決問題的方式。它們追求的宗旨仍是保證系統的低耦合高內聚,指導它們的原則無非就是封裝變化,責任單一,面向接口編程等設計原則。

參考連接:http://www.cnblogs.com/zhili/p/DesignPatternSummery.html

相關文章
相關標籤/搜索