軟件的可維護(hù)性和可復(fù)用性
知名軟件大師Robert C.Martin認(rèn)為一個(gè)可維護(hù)性(Maintainability) 較低的軟件設(shè)計(jì)双仍,通常由于如下4個(gè)原因造成:
- 過于僵硬(Rigidity)
- 過于脆弱(Fragility)
- 復(fù)用率低(Immobility)
- 黏度過高(Viscosity)
軟件工程和建模大師Peter Coad認(rèn)為妇斤,一個(gè)好的系統(tǒng)設(shè)計(jì)應(yīng)該具備如下三個(gè)性質(zhì):
- 可擴(kuò)展性(Extensibility)
- 靈活性(Flexibility)
- 可插入性(Pluggability)
??軟件的復(fù)用(Reuse)或重用擁有眾多優(yōu)點(diǎn),如可以提高軟件的開發(fā)效率,提高軟件質(zhì)量恕齐,節(jié)約開發(fā)成本们衙,恰當(dāng)?shù)膹?fù)用還可以改善系統(tǒng)的可維護(hù)性。面向?qū)ο笤O(shè)計(jì)復(fù)用的目標(biāo)在于實(shí)現(xiàn)支持可維護(hù)性的復(fù)用却桶。
??面向?qū)ο笤O(shè)計(jì)原則和設(shè)計(jì)模式也是對系統(tǒng)進(jìn)行合理重構(gòu)的指南針境输,重構(gòu)(Refactoring)是在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序代碼改善軟件的質(zhì)量颖系、性能嗅剖,使其程序的設(shè)計(jì)模式和架構(gòu)更趨合理,提高軟件的擴(kuò)展性和維護(hù)性嘁扼。
常用的面向?qū)ο笤O(shè)計(jì)原則包括7個(gè)信粮,這些原則并不是孤立存在的,它們相互依賴趁啸,相互補(bǔ)充强缘。
- 開閉原則(Open Closed Principle,OCP)
- 單一職責(zé)原則(Single Responsibility Principle, SRP)
- 里氏替換原則(Liskov Substitution Principle不傅,LSP)
- 依賴倒置原則(Dependency Inversion Principle旅掂,DIP)
- 接口隔離原則(Interface Segregation Principle,ISP)
- 合成/聚合復(fù)用原則(Composite/Aggregate Reuse Principle访娶,C/ARP)
- 最少知識原則(Least Knowledge Principle商虐,LKP)或者迪米特法則(Law of Demeter,LOD)
設(shè)計(jì)原則名稱 | 簡單定義 |
---|---|
開閉原則 | 對擴(kuò)展開放,對修改關(guān)閉 |
單一職責(zé)原則 | 一個(gè)類只負(fù)責(zé)一個(gè)功能領(lǐng)域中的相應(yīng)職責(zé) |
里氏替換原則 | 所有引用基類的地方必須能透明地使用其子類的對象 |
依賴倒置原則 | 依賴于抽象秘车,不能依賴于具體實(shí)現(xiàn) |
接口隔離原則 | 類之間的依賴關(guān)系應(yīng)該建立在最小的接口上 |
合成/聚合復(fù)用原則 | 盡量使用合成/聚合典勇,而不是通過繼承達(dá)到復(fù)用的目的 |
迪米特法則 | 一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少的與其他實(shí)體發(fā)生相互作用 |
-
開閉原則(OCP)
定義
??一個(gè)軟件實(shí)體應(yīng)當(dāng)對擴(kuò)展開放,對修改關(guān)閉鲫尊。也就是說當(dāng)應(yīng)用的需求改變時(shí)痴柔,在不修改軟件實(shí)體的源代碼或者二進(jìn)制代碼的前提下,可以擴(kuò)展模塊的功能疫向,使其滿足新的需求咳蔚。
作用
??開閉原則是面向?qū)ο蟪绦蛟O(shè)計(jì)的終極目標(biāo),它使軟件實(shí)體擁有一定的適應(yīng)性和靈活性的同時(shí)具備穩(wěn)定性和延續(xù)性搔驼。具體來說谈火,其作用如下:
- 對軟件測試的影響
軟件遵守開閉原則的話,軟件測試時(shí)只需要對擴(kuò)展的代碼進(jìn)行測試就可以舌涨,因?yàn)樵械臏y試代碼仍然能夠正常運(yùn)行糯耍。 - 可以提高代碼的可復(fù)用性
粒度越小,被復(fù)用的可能性就越大囊嘉;在面向?qū)ο蟮某绦蛟O(shè)計(jì)中温技,根據(jù)原子和抽象編程可以提高代碼的可復(fù)用性。 - 可以提高軟件的可維護(hù)性
遵守開閉原則的軟件扭粱,其穩(wěn)定性高和延續(xù)性強(qiáng)舵鳞,從而易于擴(kuò)展和維護(hù)。
-
單一職責(zé)原則(SRP)
定義
??單一職責(zé)原則規(guī)定一個(gè)類應(yīng)該有且僅有一個(gè)引起它變化的原因琢蛤,否則類應(yīng)該被拆分蜓堕。
該原則提出對象不應(yīng)該承擔(dān)太多職責(zé),如果一個(gè)對象承擔(dān)太多的職責(zé)博其,至少存在以下兩個(gè)缺點(diǎn):
1.一個(gè)職責(zé)的變化可能會削弱或者抑制這個(gè)類實(shí)現(xiàn)其他職責(zé)的能力套才;
2.當(dāng)客戶端需要該對象的某一個(gè)職責(zé)時(shí),不得不將其他不需要的職責(zé)全都包含進(jìn)來慕淡,從而造成冗余代碼或代碼的浪費(fèi)背伴。
作用
??單一職責(zé)原則的核心就是控制類的粒度大小、將對象解耦峰髓、提高其內(nèi)聚性傻寂。具體來說,其作用如下:
1.降低類的復(fù)雜度儿普。
2.提高類的可讀性崎逃。
3.提高系統(tǒng)的可維護(hù)性掷倔。
4.變更引起的風(fēng)險(xiǎn)降低眉孩。
-
里氏替換原則(LSP)
定義
??里氏替換原則主要闡述了有關(guān)繼承的一些原則,也就是什么時(shí)候應(yīng)該使用繼承,什么時(shí)候不應(yīng)該使用繼承浪汪,以及其中蘊(yùn)含的原理巴柿。里氏替換原是繼承復(fù)用的基礎(chǔ),它反映了基類與子類之間的關(guān)系死遭,是對開閉原則的補(bǔ)充广恢,是對實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。
作用
- 里氏替換原則是實(shí)現(xiàn)開閉原則的重要方式之一呀潭。
- 它克服了繼承中重寫父類造成的可復(fù)用性變差的缺點(diǎn)钉迷。
- 它是動作正確性的保證。即類的擴(kuò)展不會給已有的系統(tǒng)引入新的錯(cuò)誤钠署,降低代碼出錯(cuò)的可能性糠聪。
- 加強(qiáng)程序的健壯性,同時(shí)變更時(shí)可以做到非常好的兼容性谐鼎,提高程序的維護(hù)性舰蟆、可擴(kuò)展性,降低需求變更時(shí)引入的風(fēng)險(xiǎn)狸棍。
-
依賴倒置原則(DIP)
定義
??高層模塊不應(yīng)該依賴低層模塊身害,兩者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié)草戈,細(xì)節(jié)應(yīng)該依賴抽象塌鸯。其核心思想是:要面向接口編程,不要面向?qū)崿F(xiàn)編程猾瘸。
??依賴倒置原則是實(shí)現(xiàn)開閉原則的重要途徑之一界赔,它降低了客戶與實(shí)現(xiàn)模塊之間的耦合。
??由于在軟件設(shè)計(jì)中牵触,細(xì)節(jié)具有多變性淮悼,而抽象層則相對穩(wěn)定,因此以抽象為基礎(chǔ)搭建起來的架構(gòu)要比以細(xì)節(jié)為基礎(chǔ)搭建起來的架構(gòu)要穩(wěn)定得多揽思。這里的抽象指的是接口或者抽象類袜腥,而細(xì)節(jié)是指具體的實(shí)現(xiàn)類。
??使用接口或者抽象類的目的是制定好規(guī)范和契約钉汗,而不去涉及任何具體的操作羹令,把展現(xiàn)細(xì)節(jié)的任務(wù)交給它們的實(shí)現(xiàn)類去完成。
作用
1.可以降低類間的耦合性损痰。
2.可以提高系統(tǒng)的穩(wěn)定性福侈。
3.可以減少并行開發(fā)引起的風(fēng)險(xiǎn)。
4.可以提高代碼的可讀性和可維護(hù)性卢未。
-
接口隔離原則(ISP)
定義
??一個(gè)類對另一個(gè)類的依賴應(yīng)該建立在最小的接口上肪凛。也就是說要為各個(gè)類建立它們需要的專用接口堰汉,而不要試圖去建立一個(gè)很龐大的接口供所有依賴它的類去調(diào)用。
接口隔離原則和單一職責(zé)都是為了提高類的內(nèi)聚性伟墙、降低它們之間的耦合性翘鸭,體現(xiàn)了封裝的思想,但兩者是不同的:
- 單一職責(zé)原則注重的是職責(zé)戳葵,而接口隔離原則注重的是對接口依賴的隔離就乓。
- 單一職責(zé)原則主要是約束類,它針對的是程序中的實(shí)現(xiàn)和細(xì)節(jié)拱烁;接口隔離原則主要約束接口生蚁,主要針對抽象和程序整體框架的構(gòu)建。
作用
1.提高系統(tǒng)的靈活性和可維護(hù)性
將臃腫龐大的接口分解為多個(gè)粒度小的接口戏自,可以預(yù)防外來變更的擴(kuò)散守伸。
2.降低系統(tǒng)的耦合性
接口隔離提高了系統(tǒng)的內(nèi)聚性,減少了對外交互浦妄。
3.保證系統(tǒng)的穩(wěn)定性
如果接口的粒度大小定義合理尼摹,能夠保證系統(tǒng)的穩(wěn)定性;如果定義過小剂娄,則會造成接口數(shù)量過多蠢涝,使設(shè)計(jì)復(fù)雜化;如果定義太大阅懦,靈活性降低和二,無法提供定制服務(wù),給整體項(xiàng)目帶來無法預(yù)料的風(fēng)險(xiǎn)耳胎。
4.使用多個(gè)專門的接口還能夠體現(xiàn)對象的層次
因?yàn)榭梢酝ㄟ^接口的繼承惯吕,實(shí)現(xiàn)對總接口的定義。
5.能減少項(xiàng)目工程中的代碼冗余怕午。
過大的大接口里面通常放置許多不用的方法废登,當(dāng)實(shí)現(xiàn)這個(gè)接口的時(shí)候,被迫設(shè)計(jì)冗余的代碼郁惜。
-
合成/聚合復(fù)用原則(C/ARP)
定義
??合成/聚合復(fù)用原則要求在軟件復(fù)用時(shí)堡距,要盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來實(shí)現(xiàn)兆蕉。如果要使用繼承關(guān)系羽戒,則必須嚴(yán)格遵循里氏替換原則。合成復(fù)用原則同里氏替換原則相輔相成的虎韵,兩者都是開閉原則的具體實(shí)現(xiàn)規(guī)范易稠。
作用
1.維持類的封裝性
因?yàn)槌煞謱ο蟮膬?nèi)部細(xì)節(jié)是新對象看不見的,所以這種復(fù)用又稱為“黑箱”復(fù)用包蓝。
2.新舊類之間的耦合度低
這種復(fù)用所需的依賴較少驶社,新對象存取成分對象的唯一方法是通過成分對象的接口呆奕。
3.復(fù)用的靈活性高
這種復(fù)用可以在運(yùn)行時(shí)動態(tài)進(jìn)行,新對象可以動態(tài)地引用與成分對象類型相同的對象衬吆。
-
迪米特法則(LOD)/最少知識原則(LKP)
定義
??迪米特法則要求只與你的直接朋友交談,不跟“陌生人”說話绳泉。也就是說逊抡,如果兩個(gè)軟件實(shí)體無須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用零酪,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用冒嫡。其目的是降低類之間的耦合度,提高模塊的相對獨(dú)立性四苇。
??迪米特法則中的“朋友”是指:當(dāng)前對象本身孝凌、當(dāng)前對象的成員對象、當(dāng)前對象所創(chuàng)建的對象月腋、當(dāng)前對象的方法參數(shù)等蟀架,這些對象同當(dāng)前對象存在關(guān)聯(lián)、聚合或組合關(guān)系榆骚,可以直接訪問這些對象的方法片拍。
作用
1.提高模塊的相對獨(dú)立性,降低類之間的耦合度妓肢。
2.親合度降低捌省,從而提高了類的可復(fù)用率和系統(tǒng)的擴(kuò)展性。