學(xué)習(xí)完整課程請(qǐng)移步 互聯(lián)網(wǎng) Java 全棧工程師
口訣
為了便于記憶,我們可以使用一個(gè)口訣來(lái)記憶面向?qū)ο笤O(shè)計(jì)原則:開(kāi)口合里最單依
- 開(kāi):開(kāi)閉原則
- 口:接口隔離原則
- 合:組合/聚合原則
- 里:里式替換原則
- 最:最少知識(shí)原則(迪米特法則)
- 單:?jiǎn)我宦氊?zé)原則
- 依:依賴倒置原則
開(kāi)閉原則(Open-Closed Principle, OCP)
一個(gè)軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開(kāi)發(fā),對(duì)修改關(guān)閉.說(shuō)的是,再設(shè)計(jì)一個(gè)模塊的時(shí)候,應(yīng)當(dāng)使這個(gè)模塊可以在不被修改的前提下被擴(kuò)展.換言之,應(yīng)當(dāng)可以在不必修改源代碼的情況下改變這個(gè)模塊的行為,在保持系統(tǒng)一定穩(wěn)定性的基礎(chǔ)上,對(duì)系統(tǒng)進(jìn)行擴(kuò)展。這是面向?qū)ο笤O(shè)計(jì)(OOD)的基石,也是最重要的原則。
接口隔離原則(Interface Segregation Principle, ISP)
- 一個(gè)類(lèi)對(duì)另外一個(gè)類(lèi)的依賴是建立在最小的接口上。
- 使用多個(gè)專(zhuān)門(mén)的接口比使用單一的總接口要好.根據(jù)客戶需要的不同,而為不同的客戶端提供不同的服務(wù)是一種應(yīng)當(dāng)?shù)玫焦膭?lì)的做法.就像"看人下菜碟"一樣,要看客人是誰(shuí),再提供不同檔次的飯菜.
- 胖接口會(huì)導(dǎo)致他們的客戶程序之間產(chǎn)生不正常的并且有害的耦合關(guān)系.當(dāng)一個(gè)客戶程序要求該胖接口進(jìn)行一個(gè)改動(dòng)時(shí),會(huì)影響到所有其他的客戶程序.因此客戶程序應(yīng)該僅僅依賴他們實(shí)際需要調(diào)用的方法.
組合/聚合復(fù)用原則(Composite/Aggregate Reuse Principle,CARP)
在一個(gè)新的對(duì)象里面使用一些已有的對(duì)象,使之成為新對(duì)象的一部分;新的對(duì)象通過(guò)這些向?qū)ο蟮奈蛇_(dá)到復(fù)用已有功能的目的.這個(gè)設(shè)計(jì)原則有另一個(gè)簡(jiǎn)短的表述:要盡量使用合成/聚合,盡量不要使用繼承.
里氏代換原則(Liskov Substitution Principle,LSP)
由 Barbar Liskov (芭芭拉.里氏) 提出,是繼承復(fù)用的基石。
所有引用基類(lèi)的地方必須透明的使用其子類(lèi)的對(duì)象。只要父類(lèi)能出現(xiàn)的地方子類(lèi)也可以出現(xiàn),而且替換為子類(lèi)不會(huì)產(chǎn)生任何錯(cuò)誤或異常,但是反過(guò)來(lái)就不行,有子類(lèi)出現(xiàn)的地方,父類(lèi)未必就能適應(yīng)。
最少知識(shí)原則(Least Knowledge Principle,LKP)
一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象有盡可能少的了解.
沒(méi)有任何一個(gè)其他的 OO 設(shè)計(jì)原則象迪米特法則這樣有如此之多的表述方式,如下幾種:
- 只與你直接的朋友們通信(Only talk to your immediate friends)
- 不要跟"陌生人"說(shuō)話(Don't talk to strangers)
- 每一個(gè)軟件單位對(duì)其他的單位都只有最少的知識(shí),而且局限于那些本單位密切相關(guān)的軟件單位
就是說(shuō),如果兩個(gè)類(lèi)不必彼此直接通信,那么這兩個(gè)類(lèi)就不應(yīng)當(dāng)發(fā)生直接的相互作用,如果其中的一個(gè)類(lèi)需要調(diào)用另一個(gè)類(lèi)的某一個(gè)方法的話,可以通過(guò)第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。
單一職責(zé)原則(Simple responsibility pinciple,SRP)
就一個(gè)類(lèi)而言,應(yīng)該僅有一個(gè)引起它變化的原因,如果你能想到多于一個(gè)的動(dòng)機(jī)去改變一個(gè)類(lèi),那么這個(gè)類(lèi)就具有多于一個(gè)的職責(zé).應(yīng)該把多于的指責(zé)分離出去,分別再創(chuàng)建一些類(lèi)來(lái)完成每一個(gè)職責(zé).
依賴倒置原則(Dependence Inversion Principle)
要求客戶端依賴于抽象耦合.
- 模塊間的依賴通過(guò)抽象發(fā)生,實(shí)現(xiàn)類(lèi)之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系是通過(guò)接口或抽象類(lèi)產(chǎn)生的。
- 接口或抽象類(lèi)不依賴實(shí)現(xiàn)類(lèi)
- 實(shí)現(xiàn)類(lèi)依賴接口或抽象類(lèi)
采用依賴倒置原則可以減少類(lèi)間的耦合性,提高系統(tǒng)的穩(wěn)定,降低并行開(kāi)發(fā)引起的風(fēng)險(xiǎn),提高代碼的可讀性和可維護(hù)性。