1、單一職責(zé)原則(SRP)
定義:應(yīng)該有且僅有一個(gè)原因引起類變化。
我的理解就是一個(gè)類只做一件事(只關(guān)心自己的事),也體現(xiàn)了對象的封裝。
單一職責(zé)的好處:
1、類的復(fù)雜性降低,實(shí)現(xiàn)什么職責(zé)都有清晰明確的定義;
2、可讀性高(復(fù)雜度降低,可讀性就會(huì)變高);
3、可維護(hù)性高(可讀性高就相對來說好維護(hù));
4、變更引起的風(fēng)險(xiǎn)低(一個(gè)接口單一職責(zé)做的好[拆分的好],當(dāng)接口修改只會(huì)對當(dāng)前實(shí)現(xiàn)類有影響,對其他接口無影響,對系統(tǒng)的擴(kuò)展性和維護(hù)性都很有幫助)
接口拆分功能一定要清晰,每一個(gè)method不能太籠統(tǒng),功能細(xì)化,職責(zé)分好。
單一職責(zé)對于接口、類、方法都適用,平時(shí)開發(fā)多想想是否考慮周全,是否適用于單一職責(zé)。
作者在這里提醒道:
接口一定要做到單一職責(zé),類的設(shè)計(jì)盡量做到只有一個(gè)原因引起變化。
2、里氏替換原則(LSP)
定義:所有引用基類的地方必需能透明地使用其子類對象。
更加通俗的定義:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。
里氏替換原則為良好的繼承定義了一個(gè)規(guī)范,包含了4層含義:
1、子類必需完全實(shí)現(xiàn)父類的方法(如果不能完整實(shí)現(xiàn)父類的方法,可以使用依賴、聚集、組合等關(guān)系代替);
在類中調(diào)用其他類務(wù)必要適用父類或接口,如果不能使用父類或接口,則說明類的設(shè)計(jì)違背了LSP原則;
如果子類不能完整地實(shí)現(xiàn)父類的方法,或者父類的方法在子類中發(fā)生“畸變”,則建議斷開父子繼承關(guān)系,采用依賴、聚集、組合等關(guān)系代替繼承。(作者拿真槍和玩具槍做的比喻)
也有一種定義是:子類可以實(shí)現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法。
?????? 父類中定義的相當(dāng)于一種規(guī)范和契約;不要輕易改變。
2、子類可以有自己的個(gè)性(子類中可以增加自己特有的方法);
3、覆蓋或?qū)崿F(xiàn)父類的方法時(shí)輸入?yún)?shù)可以被放大;
4、覆蓋或?qū)崿F(xiàn)父類大方法時(shí)輸出結(jié)果(返回值)可以被縮??;
目的就是增強(qiáng)程序的健壯性。
3、依賴倒置原則(DIP)
含義:
1、高層模塊不應(yīng)該依賴底層模塊,兩者都應(yīng)該依賴其抽象;
每一個(gè)邏輯的實(shí)現(xiàn)都是由原子邏輯組成,不可分割的原子邏輯就是低層模塊,原子邏輯再組裝后就是高層模塊。
2、抽象不應(yīng)該依賴細(xì)節(jié);
3、細(xì)節(jié)應(yīng)該依賴抽象。
在Java中的體現(xiàn)是:
1、模塊間的依賴通過抽象發(fā)生,實(shí)現(xiàn)類之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系是通過接口或抽象類產(chǎn)生的;
2、接口或抽象類不依賴于實(shí)現(xiàn)類;
3、實(shí)現(xiàn)類依賴于接口或抽象類。
最佳實(shí)踐:
1、每個(gè)類盡量都有接口或抽象類,或者抽象類和接口都具備;
2、變量的表面類型盡量是接口或抽象類;
3、任何類都不應(yīng)該從具體類派生;
4、盡量不要覆寫基類的方法;
5、結(jié)合里氏替換原則使用。
:接口負(fù)責(zé)定義public屬性和方法,并且聲明與其他類的依賴關(guān)系,抽象類負(fù)責(zé)公共構(gòu)造部分的實(shí)現(xiàn),實(shí)現(xiàn)類準(zhǔn)確的實(shí)現(xiàn)業(yè)務(wù)邏輯
,同時(shí)在適當(dāng)?shù)臅r(shí)候?qū)Ω割愡M(jìn)行細(xì)化。
總體思想就是面向接口編程