本文內(nèi)容整理自《Android之大話設(shè)計(jì)模式》一書(shū)
五大設(shè)計(jì)原則:
- 單一職責(zé)原則
- 開(kāi)放封閉原則
- 里氏代換原則
- 迪米特原則
- 合成聚合復(fù)用原則
單一職責(zé)原則Single Responsibility Principle
就一個(gè)類(lèi)而言胞得,應(yīng)該僅有一個(gè)引起它變化的原因撼港。換句話說(shuō),一個(gè)類(lèi)的功能要單一,只做與它相關(guān)的事情葱她。
如果一個(gè)完成額外的不太相關(guān)的功能或者完成其它類(lèi)的功能梆掸,這就會(huì)使得一個(gè)引起一個(gè)類(lèi)變化的因素太多解寝,如果類(lèi)的一處需要修改驼仪,其它和它相關(guān)連的代碼都會(huì)受到影響沽甥,這就直接導(dǎo)致一旦系統(tǒng)出現(xiàn)了問(wèn)題就難以調(diào)試?yán)Ь成睿瑫r(shí)這樣也非常不利于維護(hù)。
現(xiàn)在軟件開(kāi)發(fā)的經(jīng)典模式MVC模式摆舟,也非常好的體現(xiàn)了單一職責(zé)原則亥曹。
MVC(Model-View-Control)就是模型、視圖恨诱、控制器三層架構(gòu)模式媳瞪,其中
M是指數(shù)據(jù)模型、V是指用戶界面照宝、C則是控制器蛇受。采用MVC模式使得數(shù)據(jù)和表現(xiàn)相分離,同一個(gè)數(shù)據(jù)層可以有不同的顯示層厕鹃。數(shù)據(jù)層和顯示層的改變互不影響兢仰。這就非常有利于提高軟件的可維護(hù)性和可復(fù)用性,同時(shí)也方便了軟件的管理工作和提高軟件開(kāi)發(fā)效率剂碴。
優(yōu)點(diǎn):
代碼整潔(可讀性強(qiáng))把将、便于修改、可維護(hù)性忆矛、可擴(kuò)展性強(qiáng)
開(kāi)放封閉原則Open-Closed Principle
開(kāi)放封閉原則是所有面向?qū)ο笤瓌t的核心察蹲。
一個(gè)軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開(kāi)放,則修改關(guān)閉催训。對(duì)擴(kuò)展開(kāi)放洽议,意味著有新的需求或變化時(shí),可以對(duì)現(xiàn)有代碼進(jìn)行擴(kuò)展漫拭,以適應(yīng)新的情況亚兄;對(duì)修改封閉,意味著類(lèi)一旦設(shè)計(jì)完成采驻,就可以獨(dú)立完成其工作审胚,而不要對(duì)類(lèi)進(jìn)行任何修改。
如何做到開(kāi)放封閉原則呢挑宠?答案是:封裝變化,依賴接口和抽象類(lèi)颓影,而不要依賴具體實(shí)現(xiàn)類(lèi)各淀。因?yàn)榻涌诤统橄箢?lèi)是穩(wěn)定的,他們是一種對(duì)客戶端的一種承諾诡挂,是相對(duì)不變的碎浇。如果以后需要擴(kuò)展或者開(kāi)發(fā)新的功能临谱,只需要實(shí)現(xiàn)或者繼承接口或者抽象類(lèi)即可覆蓋或者擴(kuò)展新的功能,這樣做同時(shí)也不回影響新的功能奴璃。這就很好的做到了對(duì)擴(kuò)展開(kāi)放悉默、對(duì)修改關(guān)閉。
一個(gè)系統(tǒng)總會(huì)有要變化的地方苟穆,“世界上沒(méi)有一個(gè)不邊的軟件”抄课、“需求總是在改變”。我們要做的不是消滅變化雳旅,而是把變化隔離開(kāi)來(lái)跟磨,并對(duì)其進(jìn)行封裝。我們無(wú)法控制變化攒盈,但是我們可以預(yù)則哪里會(huì)發(fā)生變法抵拘。把要變化的地方抽象起來(lái),這樣以后再面臨變化的時(shí)候我們就可以盡量的擴(kuò)展型豁,而無(wú)須改變以后的代碼僵蛛。
優(yōu)點(diǎn):
- 封裝變化,可擴(kuò)展性強(qiáng)
- “需求總是在變化迎变〕湮荆”
- “世界上沒(méi)有一個(gè)軟件是不變的∈贤悖”
- “針對(duì)抽象編程喉酌,不要針對(duì)實(shí)現(xiàn)編程”么”
里氏代換原則Liskov Substitution Principle
一個(gè)軟件實(shí)體如果使用的是基類(lèi)的話泪电,那么也一定適用于其子類(lèi),而且它根本覺(jué)察不出 使用的是基類(lèi)對(duì)象還是子類(lèi)對(duì)象纪铺;反過(guò)來(lái)的代換這是不成立的相速,即:如果一個(gè)軟件實(shí)體使用一個(gè)類(lèi)的子類(lèi)對(duì)象,那么它不能夠適用于基類(lèi)對(duì)象鲜锚。
里氏代換原則由Liskov女士提出突诬,后來(lái)軟件工程大師Robert C. Martin
把里氏代換原則最終簡(jiǎn)化為一句話:“Subtypes must besubstitutable for their base types”。也就是芜繁,子類(lèi)必須能夠替換成它們的基類(lèi)旺隙。
里氏代換原則講的是基類(lèi)和子類(lèi)的關(guān)系,只有這種關(guān)系存在的時(shí)候里氏代換原則才能夠成立骏令。 里氏代換原則是實(shí)現(xiàn)開(kāi)放封閉原則的具體規(guī)范蔬捷。這是因?yàn)椋簩?shí)現(xiàn)開(kāi)放封閉原則的關(guān)鍵是進(jìn)行抽象,而繼承關(guān)系又是抽象的一種具體實(shí)現(xiàn),這樣LSP就可以確敝芄眨基類(lèi)和子類(lèi)關(guān)系的正確性铡俐,進(jìn)而為實(shí)現(xiàn)開(kāi)放封閉原則服務(wù)。
優(yōu)點(diǎn):
- 可擴(kuò)展性
里氏代換原則是很多其它設(shè)計(jì)模式的基礎(chǔ)妥粟。
迪米特原則Law of Demeter
迪米特法則(Law of Demeter审丘,簡(jiǎn)寫(xiě)LoD)又叫做最少知識(shí)原則(LeastKnowledge Principle簡(jiǎn)寫(xiě)LKP),也就是說(shuō)勾给,一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象盡可能少的了解滩报,不和陌生人說(shuō)話。
狹義的迪米特法則是指:如果兩個(gè)類(lèi)不必彼此直接通信锦秒,那么這兩個(gè)類(lèi)就不應(yīng)當(dāng)發(fā)生直接的相互作用露泊。如果其中一個(gè)類(lèi)需要調(diào)用另一類(lèi)的某一個(gè)方法的話,可以通過(guò)第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用旅择。
廣義的迪米特法則是指:一個(gè)模塊設(shè)計(jì)的好壞的一個(gè)重要標(biāo)志就是該模塊在多大程度上講自己的內(nèi)部數(shù)據(jù)與實(shí)現(xiàn)的有關(guān)細(xì)節(jié)隱藏起來(lái)惭笑。
在運(yùn)用迪米特法則到系統(tǒng)的設(shè)計(jì)中時(shí),要注意以下幾點(diǎn):
第一:在類(lèi)的劃分上,應(yīng)當(dāng)創(chuàng)建弱耦合的類(lèi)生真,類(lèi)與類(lèi)之間的耦合越弱沉噩,就越有利于實(shí)現(xiàn)可復(fù)用的目標(biāo)。
第二:在類(lèi)的結(jié)構(gòu)設(shè)計(jì)上柱蟀,每個(gè)類(lèi)都應(yīng)該降低成員的訪問(wèn)權(quán)限川蒙。
第三:在類(lèi)的設(shè)計(jì)上,只要有可能长已,一個(gè)類(lèi)應(yīng)當(dāng)設(shè)計(jì)成不變的類(lèi)畜眨。
第四:在對(duì)其他類(lèi)的應(yīng)用上,一個(gè)對(duì)象對(duì)其他類(lèi)的對(duì)象的應(yīng)用應(yīng)該降到最低术瓮。
第五:盡量限制局部變量的有效范圍康聂。
但是過(guò)度使用迪米特法則,也會(huì)造成系統(tǒng)的不同模塊之間的通信效率降低胞四,使系統(tǒng)的不同模塊之間不容易協(xié)調(diào)等缺點(diǎn)恬汁。如果類(lèi)之間需要通信就通過(guò)第三方轉(zhuǎn)發(fā)的方式,這就直接導(dǎo)致了系統(tǒng)中存在大量的中介類(lèi)辜伟,這些類(lèi)存在的唯一原因是為了傳遞類(lèi)與類(lèi)之間的相互調(diào)用關(guān)系氓侧,這就毫無(wú)疑問(wèn)的增加了系統(tǒng)的復(fù)雜度。解決這個(gè)問(wèn)題的方式是:使用依賴倒轉(zhuǎn)原則(通俗的講就是要針對(duì)接口編程导狡,不要針對(duì)具體編程)约巷,這要就可以是調(diào)用方和被調(diào)用方之間有了一個(gè)抽象層,被調(diào)用方在遵循抽象層的前提下就可以自由的變化旱捧,此時(shí)抽象層成了調(diào)用方的朋友独郎。
合成聚合復(fù)用原則(Composite Aggregate Reuse Principle,簡(jiǎn)稱CARP)
合成聚合復(fù)用原則是指在一個(gè)新的對(duì)象中使用原來(lái)已經(jīng)存在的一些對(duì)象,是這些原來(lái)已經(jīng)存在的對(duì)象稱為新對(duì)象的一部分,新的對(duì)象通過(guò)向這些原來(lái)已經(jīng)具有的對(duì)象委派相應(yīng)的動(dòng)作或者命令達(dá)到復(fù)用已有功能的目的囚聚。
合成復(fù)用原則跟簡(jiǎn)潔的表述是:要盡量使用合成和聚合,盡量不要使用繼承标锄。
為何“要盡量使用合成和聚合顽铸,盡量不要使用繼承”呢?這是因?yàn)椋旱谝涣匣剩^承復(fù)用破壞包裝谓松,它把超類(lèi)的實(shí)現(xiàn)細(xì)節(jié)直接暴露給了子類(lèi),這違背了信息隱藏的原則践剂;第二:如果超類(lèi)發(fā)生了改變鬼譬,那么子類(lèi)也要發(fā)生相應(yīng)的改變,這就直接導(dǎo)致了類(lèi)與類(lèi)之間的高耦合逊脯,不利于類(lèi)的擴(kuò)展优质、復(fù)用、維護(hù)等军洼,也帶來(lái)了系統(tǒng)僵硬和脆弱的設(shè)計(jì)巩螃。而是用合成和聚合的時(shí)候新對(duì)象和已有對(duì)象的交互往往是通過(guò)接口或者抽象類(lèi)進(jìn)行的,就可以很好的避免上面的不足匕争,而且這也可以讓每一個(gè)新的類(lèi)專注于實(shí)現(xiàn)自己的任務(wù)避乏,符合單一職責(zé)原則。