1. 程式人生 > >C#設計模式(3)

C#設計模式(3)

三、 依賴倒置原則(DIP)

依賴倒置(Dependence Inversion Principle)原則講的是:要依賴於抽象,不要依賴於具體。

簡單的說,依賴倒置原則要求客戶端依賴於抽象耦合。原則表述:

抽象不應當依賴於細節;細節應當依賴於抽象;
要針對介面程式設計,不針對實現程式設計。

反面例子:

 

缺點:耦合太緊密,Light發生變化將影響ToggleSwitch。

解決辦法一:
將Light作成Abstract,然後具體類繼承自Light。

 

優點:ToggleSwitch依賴於抽象類Light,具有更高的穩定性,而BulbLight與TubeLight繼承自Light,可以根據"開放-封閉"原則進行擴充套件。只要Light不發生變化,BulbLight與TubeLight的變化就不會波及ToggleSwitch。

缺點:如果用ToggleSwitch控制一臺電視就很困難了。總不能讓TV繼承自Light吧。

解決方法二:
 

優點:更為通用、更為穩定。

結論:
使用傳統過程化程式設計所建立的依賴關係,策略依賴於細節,這是糟糕的,因為策略受到細節改變的影響。依賴倒置原則使細節和策略都依賴於抽象,抽象的穩定性決定了系統的穩定性。

四、 介面隔離原則(ISP)

介面隔離原則(Interface Segregation Principle)講的是:使用多個專門的介面比使用單一的總介面總要好。換而言之,從一個客戶類的角度來講:一個類對另外一個類的依賴性應當是建立在最小介面上的。

過於臃腫的介面是對介面的汙染。不應該強迫客戶依賴於它們不用的方法。

My object-oriented umbrella(摘自Design Patterns Explained)

Let me tell you about my great umbrella. It is large enough to get into! In fact, three or four other people can get in it with me. While we are in it, staying out of the rain, I can move it from one place to another. It has a stereo system to keep me entertained while I stay dry. Amazingly enough, it can also condition the air to make it warmer or colder. It is one cool umbrella.

My umbrella is convenient. It sits there waiting for me. It has wheels on it so that I do not have to carry it around. I don't even have to push it because it can propel itself. Sometimes, I will open the top of my umbrella to let in the sun. (Why I am using my umbrella when it is sunny outside is beyond me!)

In Seattle, there are hundreds of thousands of these umbrellas in all kinds of colors. Most people call them cars.

實現方法:
1、 使用委託分離介面
2、 使用多重繼承分離介面

五、 合成/聚合複用原則(CARP)

合成/聚合複用原則(Composite/Aggregate Reuse Principle或CARP)經常又叫做合成複用原則(Composite Reuse Principle或CRP),就是在一個新的物件裡面使用一些已有的物件,使之成為新物件的一部分;新物件通過向這些物件的委派達到複用已有功能的目的。

簡而言之,要儘量使用合成/聚合,儘量不要使用繼承。

o Design to interfaces.
o Favor composition over inheritance.
o Find what varies and encapsulate it.
(摘自:Design Patterns Explained)

區分"Has-A"與"Is-A"

"Is-A"是嚴格的分類學意義上定義,意思是一個類是另一個類的"一種"。而"Has-A"則不同,它表示某一個角色具有某一項責任。

導致錯誤的使用繼承而不是合成/聚合的一個常見的原因是錯誤的把"Has-A"當作"Is-A"。

例如:
 

實際上,僱員、經理、學生描述的是一種角色,比如一個人是"經理"必然是"僱員",另外一個人可能是"學生僱員",在上面的設計中,一個人無法同時擁有多個角色,是"僱員"就不能再是"學生"了,這顯然是不合理的。

錯誤源於把"角色"的等級結構與"人"的等級結構混淆起來,誤把"Has-A"當作"Is-A"。解決辦法:

 

六、 迪米特法則(LoD)

迪米特法則(Law of Demeter或簡寫LoD)又叫最少知識原則(Least Knowledge Principle或簡寫為LKP),也就是說,一個物件應當對其它物件有儘可能少的瞭解。

其它表述:
  只與你直接的朋友們通訊
  不要跟"陌生人"說話
  每一個軟體單位對其它的單位都只有最少的知識,而且侷限於那些與本單位密切相關的軟體單位。

迪米特法則與設計模式
Facade模式、Mediator模式

使民無知
《老子》第三章曰:"是以聖人之治,虛其心,實其腹,弱其志,常使民無知無慾。"使被"統治"的物件"愚昧"化,處於"無知"的狀態,可以使"統治"的成本降低。
所謂"最少知識"原則,實際上便是老子的"使民無知"的統治之術。

不相往來
《老子》雲:"小國寡民……鄰國相望,雞犬之聲相聞,民至老死,不相往來。"將被統治的物件隔離開來,使它們沒有直接的通訊,可以達到分化瓦解,繼而分而治之的效果。迪米特法則與老子的"小國寡民"的統治之術不謀而合。


參考文獻:
閻巨集,《Java與模式》,電子工業出版社
[美]James W. Cooper,《C#設計模式》,電子工業出版社
[美]Alan Shalloway  James R. Trott,《Design Patterns Explained》,中國電力出版社
[美]Robert C. Martin,《敏捷軟體開發-原則、模式與實踐》,清華大學出版社
[美]Don Box, Chris Sells,《.NET本質論 第1卷:公共語言執行庫》,中國電力出版社
http://www.dofactory.com/Patterns/Patterns.aspx

相關推薦

C#設計模式3——抽象工廠模式

1.抽象工廠模式介紹   上一篇我們瞭解了工廠模式,知道工廠模式可以解決簡單工廠的缺陷(簡單工廠新增新產品時要修改工廠類,不符合開閉原則),但是簡單工廠和工廠模式都是隻生產一種產品(前邊的簡單工廠和工廠都只生產滑鼠),實際上戴爾和惠普公司不僅生產滑鼠還生產鍵盤,為了解決系列產品的問題,就有了抽象工廠模式。我

C#設計模式3

三、 依賴倒置原則(DIP) 依賴倒置(Dependence Inversion Principle)原則講的是:要依賴於抽象,不要依賴於具體。 簡單的說,依賴倒置原則要求客戶端依賴於抽象耦合。原則表述: 抽象不應當依賴於細節;細節應當依賴於抽象;要針對介面程式設計,不針對實現程式設計。 反面例子:

C++進階語法篇—第11章 設計模式3

11.3.4模板模式 模板模式:定義一個操作中的演算法骨架,將一些步驟延遲到子類中。模板模式使得子類可以不改變一個演算法的介面即可重定義該演算法的某些特定步驟。 模板模式是行為型模式中最簡單的一種,在實際應用中會經常使用。注:模板模式和前面的類/函式模板不同。 案例:現在公司組2個隊伍,

設計模式3抽象工廠模式Abstract Factory

開始 line andro 依賴 red 單例 clas 面向接口 抽象工廠方法 設計模式(0)簡單工廠模式 設計模式(1)單例模式(Singleton) 設計模式(2)工廠方法模式(Factory Method) 源碼地址 0 抽象工廠模式簡介 0.0 抽象工廠模式定義

跟著實例學習設計模式3-工廠方法創建型

迪米特 tex 新的 類的設計 package set pre sdn sso 工廠方法屬於創建型設計模式。 設計意圖:定義一個用於創建對象的接口。讓子類決定實例化哪一個類,工廠方法使一個類的實例化延遲到其子類。 靜態工廠使用面向對象的方式,有

headfirst設計模式3—裝飾者模式

其中 拖延 穩定 放棄 等等 logs headfirst 自己的 定義 序 好久沒寫設計模式了,自從寫了兩篇之後,就放棄治療了,主要還是工作太忙了啊(借口,都是借口),過完年以後一直填坑,填了好幾個月,總算是穩定下來了,可以打打醬油了。 為什麽又重新開始寫設計模式呢?學習

【pattern】設計模式3 - Observer觀察者模式

獨立 使用 數據 技術 很多 調用 edi 基於 ace 源碼地址:https://github.com/vergilyn/design-patterns 另外一個大神很全的Github:https://github.com/iluwatar/java-design-pat

23種設計模式3:抽象工廠模式

如果 劃分 產品 升級版本 特點 client 形式 inter system 定義:為創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類。 類型:創建類模式。 類圖: 抽象工廠模式與工廠方法模式的區別 抽象工廠模式是工廠方法模式的升級版本,他用來創

C#設計模式1——設計原則

設計原則 使用設計模式的根本原因是適應變化,提高程式碼複用率,使軟體更具有可維護性和可擴充套件性。在進行設計的時候,我們需要遵循以下幾個原則:單一職責原則、開閉原則、里氏替代原則、依賴倒置原則、介面隔離原則、合成複用原則和迪米特法則。 1.單一職責原則   專業的人做專業的事,面向物件程式設計中類也是一

C#設計模式1——簡單工廠模式

void 例子 代碼復用 操作 inf 這樣的 man ger troy 1.什麽是簡單工廠   現實中的工廠負責生產產品,編程中的簡單工廠顧名思義就是一個生產對象的類,它的主要作用是封裝改變。我們在平時的工作必不可免的和各種數據庫打交道,我們就以一個數據庫服務類為例來分

設計模式3—— 建立型——建造者Builder

說明 在眾多開源框架或者jdk原始碼中常常出現Builder,build相關的類檔名或者類名,函式名。其中很多如此命名的原因就是因為使用了建造者(Builder)模式。檢視jdk原始碼不難發現,我們常用的StringBuilder類也使用了建造者模式。 建造者模式介

C#設計模式6——原型模式

1.原型模式介紹   在軟體系統開發中,有時候會遇到這樣的情況:我們需要用到多個相同例項,最簡單直接的方法是通過多次呼叫new方法來建立相同的例項。如下: Person person=new Person(){Name="jack",Age=20}; Person person2=new Pers

C#設計模式5——建造者模式

1.建造者模式介紹   在軟體開發中,有時我們要建立一個複雜的物件,這個物件由幾個子部件按一定的步驟組合而成,這時候我們就可以使用建造者模式了。說到建造者我們首先想到的是蓋房子,蓋房子簡單的說有三個步驟:打地基,砌磚,粉刷。我們就以蓋房子為例解釋建造者模式的用法。   建造者模式有三個角色:建造者,具體的

C#設計模式8——外觀模式 java設計模式之外觀模式門面模式

1.外觀模式介紹   外觀模式也被叫做門面模式,這種模式的作用是:隱藏系統的複雜性,並向客戶端提供了一個可以訪問系統的統一介面,這個統一的介面組合了子系統的多個介面。使用統一的介面使得子系統更容易被訪問或者使用。 以去醫院看病為例,去醫院看病時可能要去掛號、門診、劃價、取藥等,讓患者或患者家屬覺得很複雜,如

C#設計模式9——代理模式

1.代理模式介紹   在軟體開發中有時會遇到不能直接使用物件的問題,如我們要使用的物件在程序外,甚至在遠端的機器上,但是我們要使用這個物件的功能怎麼辦呢?代理模式就可以用來解決這個問題。舉一個生活中的例子:一個害羞男孩追求一個叫如花的女孩,但是自己不敢送禮物,就找了一個朋友代理他給如花送禮物。就以這個例子介

C#設計模式13——享元模式

1.享元模式介紹   在軟體開發中我們經常遇到多次使用相似或者相同物件的情況,如果每次使用這個物件都去new一個新的例項會很浪費資源。這時候很多人會想到前邊介紹過的一個設計模式:原型模式,原型模式通過拷貝現有物件來生成一個新的例項,使用拷貝來替代new。原型模式可以很好的解決建立多個相同/相似例項的問題,為

PHP設計模式3—— 策略模式

基本概念 策略模式是一個非常常用,且非常有用的設計模式。 簡單的說,它是當你使用大量if else邏輯時的救星。 if else 就是一種判斷上下文的環境所作出的策略,如果你把if else寫死,那麼在複雜邏輯的時候你會發現程式碼超級長,而且最蛋疼的是,當你以後要新增策略時

C++設計模式——建立型模式

     設計模式指導我們怎樣去建立、維護、分配面向物件系統中的實體類, 以獲得高內聚、低耦合的面向物件系統,從而提高系統的可維護性和可複用性。設計模式是OO的一些設計思想的一個總結(但不是全部),因此設計模式和OO的設計原則經驗沒有矛盾,而是殊

設計模式3-訪問者模式

模擬不同身份開啟窗體,實現不同的功能: class Program     {         static void Main(string[] args)         {             FORM f = new FORM();             Vi

java設計模式---3代理模式

代理模式就是這個事情是A的,A自己不做就B去代他做。代理模式分2種情況:簡單的靜態代理和稍微複雜的動態代理。 靜態代理 例項: 有個老師: public class Teacher { public void teach(String teach) { Sys