設(shè)計(jì)模式的六大原則
1鲁森、開(kāi)閉原則(Open Close Principle)
????開(kāi)閉原則的意思是:對(duì)擴(kuò)展開(kāi)放沙庐,對(duì)修改關(guān)閉。
? ? 也就是在程序需要進(jìn)行拓展的時(shí)候焰枢,不去修改原有的代碼舀患,可以熱插拔徽级,使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)聊浅。想要達(dá)到這樣的效果餐抢,需要使用接口和抽象類(lèi)。
????如果一個(gè)系統(tǒng)在擴(kuò)展時(shí)只涉及到修改配置文件低匙,而原有的代碼沒(méi)有做任何修改旷痕,該系統(tǒng)即可認(rèn)為是一個(gè)符合開(kāi)閉原則的系統(tǒng)。
2顽冶、里氏代換原則(Liskov Substitution Principle)
? ? ?里氏代換原則中說(shuō)欺抗,任何基類(lèi)可以出現(xiàn)的地方,子類(lèi)一定可以出現(xiàn)强重。
? ? 也就是說(shuō)將一個(gè)基類(lèi)對(duì)象替換成它的子類(lèi)對(duì)象绞呈,程序?qū)⒉粫?huì)產(chǎn)生任何錯(cuò)誤和異常,而反過(guò)來(lái)則不成立间景,使用的是一個(gè)子類(lèi)對(duì)象佃声,那么它不一定能夠使用基類(lèi)對(duì)象。例如一個(gè)方法接收父類(lèi)對(duì)象倘要,那么這個(gè)方法也可以接收子類(lèi)對(duì)象圾亏。由于使用基類(lèi)對(duì)象的地方都可以使用子類(lèi)對(duì)象,因此在程序中盡量使用基類(lèi)類(lèi)型來(lái)對(duì)對(duì)象進(jìn)行定義,而在運(yùn)行時(shí)再確定其子類(lèi)類(lèi)型志鹃,用子類(lèi)對(duì)象來(lái)替換父類(lèi)對(duì)象父晶。
????里氏代換原則是對(duì)開(kāi)閉原則的補(bǔ)充。實(shí)現(xiàn)開(kāi)閉原則的關(guān)鍵步驟就是抽象化弄跌,而基類(lèi)與子類(lèi)的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn)甲喝,所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。
????在使用里氏代換原則時(shí)需要注意如下幾個(gè)問(wèn)題:
? ? ? (1)子類(lèi)的所有方法必須在父類(lèi)中聲明铛只,或子類(lèi)必須實(shí)現(xiàn)父類(lèi)中聲明的所有方法埠胖。如果一個(gè)方法只存在子類(lèi)中,在父類(lèi)中不提供相應(yīng)的聲明淳玩,則無(wú)法在以父類(lèi)定義的對(duì)象中使用該方法直撤。
????? (2) 盡量把父類(lèi)設(shè)計(jì)為抽象類(lèi)或者接口,讓子類(lèi)繼承父類(lèi)或?qū)崿F(xiàn)父接口蜕着,并實(shí)現(xiàn)在父類(lèi)中聲明的方法谋竖,運(yùn)行時(shí),子類(lèi)實(shí)例替換父類(lèi)實(shí)例承匣,我們可以很方便地?cái)U(kuò)展系統(tǒng)的功能蓖乘,同時(shí)無(wú)須修改原有子類(lèi)的代碼,增加新的功能可以通過(guò)增加一個(gè)新的子類(lèi)來(lái)實(shí)現(xiàn)韧骗。
????(3)Java語(yǔ)言中嘉抒,在編譯階段,Java編譯器會(huì)檢查一個(gè)程序是否符合里氏代換原則袍暴,這是一個(gè)與實(shí)現(xiàn)無(wú)關(guān)的些侍、純語(yǔ)法意義上的檢查,但Java編譯器的檢查是有局限的政模。
3岗宣、依賴(lài)倒轉(zhuǎn)原則(Dependence Inversion Principle)
??????抽象不應(yīng)該依賴(lài)于細(xì)節(jié),細(xì)節(jié)應(yīng)當(dāng)依賴(lài)于抽象淋样,?也就是針對(duì)接口編程耗式,依賴(lài)于抽象而不依賴(lài)于具體。
?????這個(gè)原則是開(kāi)閉原則的基礎(chǔ)习蓬。
? ? ?在程序代碼中傳遞參數(shù)時(shí)或在關(guān)聯(lián)關(guān)系中纽什,盡量引用層次高的抽象層類(lèi)措嵌,即使用接口和抽象類(lèi)進(jìn)行變量類(lèi)型聲明躲叼、參數(shù)類(lèi)型聲明、方法返回類(lèi)型聲明企巢,以及數(shù)據(jù)類(lèi)型的轉(zhuǎn)換等枫慷,而不要用具體類(lèi)來(lái)做這些事情。為了確保該原則的應(yīng)用,一個(gè)具體類(lèi)應(yīng)當(dāng)只實(shí)現(xiàn)接口或抽象類(lèi)中聲明過(guò)的方法或听,而不要給出多余的方法探孝,否則將無(wú)法調(diào)用到在子類(lèi)中增加的新方法。模塊間通過(guò)抽象發(fā)生誉裆,實(shí)現(xiàn)類(lèi)之間不發(fā)生直接依賴(lài)關(guān)系顿颅,其依賴(lài)關(guān)系是通過(guò)接口或者抽象類(lèi)產(chǎn)生的。如果類(lèi)與類(lèi)直接依賴(lài)細(xì)節(jié)足丢,那么就會(huì)直接耦合粱腻,那么當(dāng)修改時(shí),就會(huì)同時(shí)修改依賴(lài)者代碼斩跌,這樣限制了可擴(kuò)展性绍些。
????在實(shí)現(xiàn)依賴(lài)倒轉(zhuǎn)原則時(shí),我們需要針對(duì)抽象層編程耀鸦,而將具體類(lèi)的對(duì)象通過(guò)依賴(lài)注入(DependencyInjection, DI)的方式注入到其他對(duì)象中柬批,依賴(lài)注入是指當(dāng)一個(gè)對(duì)象要與其他對(duì)象發(fā)生依賴(lài)關(guān)系時(shí),通過(guò)抽象來(lái)注入所依賴(lài)的對(duì)象袖订。常用的注入方式有三種氮帐,分別是:構(gòu)造注入,設(shè)值注入(Setter注入)和接口注入洛姑。構(gòu)造注入是指通過(guò)構(gòu)造函數(shù)來(lái)傳入具體類(lèi)的對(duì)象揪漩,設(shè)值注入是指通過(guò)Setter方法來(lái)傳入具體類(lèi)的對(duì)象,而接口注入是指通過(guò)在接口中聲明的業(yè)務(wù)方法來(lái)傳入具體類(lèi)的對(duì)象吏口。這些方法在定義時(shí)使用的是抽象類(lèi)型奄容,在運(yùn)行時(shí)再傳入具體類(lèi)型的對(duì)象,由子類(lèi)對(duì)象來(lái)覆蓋父類(lèi)對(duì)象产徊。
4昂勒、接口隔離原則(Interface Segregation Principle)
????這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好舟铜。它還有另外一個(gè)意思是:降低類(lèi)之間的耦合度戈盈。強(qiáng)調(diào)降低依賴(lài),降低耦合谆刨。
5塘娶、迪米特法則,又稱(chēng)最少知道原則(Demeter Principle)
? ??一個(gè)實(shí)體應(yīng)當(dāng)盡量少地與其他實(shí)體之間發(fā)生相互作用痊夭,使得系統(tǒng)功能模塊相對(duì)獨(dú)立刁岸。
????應(yīng)該盡量減少對(duì)象之間的交互,如果兩個(gè)對(duì)象之間不必彼此直接通信她我,那么這兩個(gè)對(duì)象就不應(yīng)當(dāng)發(fā)生任何直接的相互作用虹曙,如果其中的一個(gè)對(duì)象需要調(diào)用另一個(gè)對(duì)象的某一個(gè)方法的話(huà)迫横,可以通過(guò)第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。簡(jiǎn)言之酝碳,就是通過(guò)引入一個(gè)合理的第三者來(lái)降低現(xiàn)有對(duì)象之間的耦合度矾踱。在類(lèi)的設(shè)計(jì)上,只要有可能疏哗,一個(gè)類(lèi)型應(yīng)當(dāng)設(shè)計(jì)成不變類(lèi)呛讲。在對(duì)其他類(lèi)的引用上,一個(gè)對(duì)象對(duì)其他對(duì)象的引用應(yīng)當(dāng)降到最低返奉。
6圣蝎、單一職責(zé)原則,又稱(chēng)合成復(fù)用原則(Composite Reuse Principle)
? ? 盡量使用合成/聚合的方式衡瓶,而不是使用繼承徘公。通俗講就是我們不要讓一個(gè)類(lèi)承擔(dān)過(guò)多的職責(zé)。
????一個(gè)類(lèi)承擔(dān)的職責(zé)越多哮针,它被復(fù)用的可能性就越小关面,而且一個(gè)類(lèi)承擔(dān)的職責(zé)過(guò)多,就相當(dāng)于將這些職責(zé)耦合在一起十厢,當(dāng)其中一個(gè)職責(zé)變化時(shí)等太,可能會(huì)影響其他職責(zé)的運(yùn)作,因此要將這些職責(zé)進(jìn)行分離蛮放,將不同的職責(zé)封裝在不同的類(lèi)中缩抡,即將不同的變化原因封裝在不同的類(lèi)中,如果多個(gè)職責(zé)總是同時(shí)發(fā)生改變則可將它們封裝在同一類(lèi)中包颁。