設計模式6個基本原則學習和總結

2021-06-29 12:09:00 字數 3999 閱讀 7251

關鍵句:乙個類只負責乙個職責

看例子理解:

class animal  

} public

class client

}

執行結果不必多說,但是後面我們發現這個animal類還會包括魚,animal.breathe(「魚」),顯然常見的魚並不是通過肺來呼吸的,這時我們就需要修改了。這裡也就發生了職責擴散,職責擴撒就是由於某種原因,職責需要細分為職責1和職責2

我們可能會這樣改:

(1)修改animal類的breathe方法:(不建議的修改方式)

public

void

breathe(string animal)else

}

上面這種修改方式是很簡單,但是存在進一步的風險,假如往後的某一天,我們知道了某些魚還會用其他方式呼吸,這樣我們又要進一步修改這個類,這時我們的修改可能就會影響到 牛 羊 等呼吸方式。這也違背了單一職責原則,所以這種方式不可取。

(2)增加animal類新的breathe方法:(根據實際情況確定是否使用)

class animal  

public

void

breathe2(string animal)

}

上面修改方式,在方法級別符合單一職責原則,因為它並沒有動原來方法的**。類級別是違背單一職責原則。這種方式在類中方法足夠少的情況下可以考慮使用。

(3)細分animal類:(標準的,不違反單一職責的方式)

class terrestrial  

} class aquatic

}

上面修改的方式,修改花銷是很大的,除了將原來的animal類分解之外,還需要修改客戶端。即:

terrestrial terrestrial = new terrestrial();  

terrestrial.breathe("牛");

aquatic aquatic = new aquatic();

aquatic.breathe("魚");

所以,上面(2)(3)修改方式需要綜合專案的複雜程度等選擇使用(如何選擇使用上面已經有說到)

關鍵句:子類可以擴充套件父類的功能,但不能改變父類原有的功能

這個原則主要是針對繼承而言的,因為繼承往往有這樣的含義:父類中已經實現的方法,其實也就是針對該類部分行為的描述和定義。而若子類對這個方法進行任意修改,那麼就會造成繼承體系的破壞。

實際程式設計中,我們常常會通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的**的可復用性會比較差。

如果非要重寫父類的方法,比較通用的做法是:原來的父類和子類都繼承乙個更通俗的基類,原有的繼承關係去掉,採用依賴、聚合,組合等關係代替。

關鍵句:細節應該依賴抽象,面向介面程式設計

看例子理解這個原則:

class book  

} class mother

} public

class client

}

上面的例子有乙個mother類,有乙個book類,book類作為乙個引數傳入到mother類中,這樣,mother類就完成了對book類的讀取。

但是這時候,要增加乙個需求,mother要讀報紙,與book類相似,news*****類如下:

class news*****  

}

這時候我們就發現,mother類的narrate方法只接受book的物件,並不會讀news*****,所以我們考慮如下修改方式:

(1)mother類增加narrate1方法,傳入news*****。

絕對的坑爹設計,以後如果還有 雜誌、**要讀,那是不是會有更多方法需要增加,mother類需要不斷修改。

(2)面向介面程式設計,引入介面ireader。

inte***ce ireader
mother類與介面ireader發生依賴關係,而book和news*****都屬於讀物的範疇,他們各自都去實現ireader介面,這樣就符合依賴倒置原則了,**修改為:

class

news*****

implements

ireader

} class

book

implements

ireader

} class

mother

} public

class

client

}

遵循依賴倒置原則可以降低類之間的耦合性,提高系統的穩定性,降低修改程式造成的風險。

關鍵句:客戶端不應該依賴它不需要的介面;乙個類對另乙個類的依賴應該建立在最小的介面上

這個原則解決這樣乙個問題:

類a通過介面 i 依賴類b,類c通過同樣的介面 i 依賴類d。這是介面 i 有類b和類d的方法,但是對於類b和類d他們彼此並不需要對方的方法。這時,介面 i 的就過於臃腫,因此需要拆分。

這個原則比較好理解,這裡不再用例子解釋。需要記住的就是建立單一介面,不要建立龐大臃腫的介面,適度細化介面,介面中的方法盡量少。

關鍵句:乙個物件應該對其他物件保持最少的了解,盡量降低類與類之間的耦合

這個原則也可以這樣理解,類僅與直接的朋友通訊。(直接的朋友包括:成員變數、方法引數、方法返回值)

舉個例子,現在有如下程式:

//總公司員工

class employee

public string getid()

}//分公司員工

class subemployee

public string getid()

}

現在需要輸出整個公司員工的id,我們可能會這樣寫**:

class

subcompanymanager

return

list;

}}class

companymanager

return

list;

}public void printallemployee(subcompanymanager sub)

list

list2 = this.getallemployee();

for(employee e:list2)

}}

在分公司subcompanymanager類中建立方法getallemployee()

在總公司companymanager類中建立方法getallemployee()和printallemployee()。

根據迪公尺特法則,comanymanager與employee是直接朋友,但是與subemployee並不是直接朋友。這樣總公司與分公司邏輯上是耦合的了。所以這種方式不可取,需要修改:

class

subcompanymanager

return

list;

}public void printemployee()

}}class

companymanager

return

list;

}public void printallemployee(subcompanymanager sub)

}}

上面方法就有效的降低了類之間耦合,僅與直接的朋友進行了通訊。

關鍵句:類、模組、功能應該對擴充套件開放,對修改關閉

開閉原則中「開」,是指對於元件功能的擴充套件是開放的,是允許對其進行功能擴充套件的;

開閉原則中「閉」,是指對於原有**的修改是封閉的,即不應該修改原有的**。

之前提到的黎克特制代換原則、依賴倒置原則、介面隔離原則,還有我們知道的抽象類、介面等等,都可以看作是開閉原則的實現方法。

設計模式基本原則

設計模式基本原則 開 閉 原則 open closed principle,或者ocp 原文 software entities should be open for extension,but closed for modification.解釋 乙個軟體實體應當對擴充套件開放,對修改關閉。黎克特...

設計模式基本原則

1 單一職責原則 類的職責要單一 不要將太多的職責放到同乙個類當中去。eg 資料結構職責類和演算法行為都放在乙個類。我們應該把資料結構和行為分開。2 開閉原則 乙個軟體實體應該對擴充套件開放,對修改關閉。可變性封裝 3 黎克特制代換原則 可以接受基類物件的地方必然要可以接受子類的物件。4 依賴倒轉原...

設計模式基本原則

設計模式基本原則 開 閉 原則 open closed principle,或者ocp 原文 software entities should be open for extension,but closed for modification.解釋 乙個軟體實體應當對擴充套件開放,對修改關閉。黎克特...