2021-05-29 軟件設(shè)計(jì)原則

在軟件開發(fā)中,為了提高軟件系統(tǒng)的可維護(hù)性和可復(fù)用性,增加軟件的可擴(kuò)展性和靈活性,程序員要盡量根據(jù)6條原則來開發(fā)程序,從而提高軟件開發(fā)效率、節(jié)約軟件開發(fā)和維護(hù)成本。

1.開閉原則(Open close principle,OCP)

對擴(kuò)展開放,對修改關(guān)閉。在程序需要拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果,簡言之,是為了使程序的擴(kuò)展性好,便于維護(hù)和升級。
想要達(dá)到這樣的效果,我們需要使用接口和抽象類。
因?yàn)槌橄箪`活性好,適應(yīng)性廣,只要抽象的合理,可以基本保持軟件架構(gòu)的穩(wěn)定。而軟件中易變的細(xì)節(jié)可以從抽象派生來的實(shí)現(xiàn)類進(jìn)行擴(kuò)展,當(dāng)軟件需要發(fā)生變化時(shí),只需要根據(jù)需求重新派生一個(gè)實(shí)現(xiàn)類擴(kuò)展就可以了。

2.里氏代換原則(Liskov substitution principle,LSP)

任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。通俗理解:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。換句話說,子類繼承父類時(shí),除了添加新的方法完成新增功能外,盡量不要重寫父類的方法。
通過重寫父類方法來完成新的功能,這樣寫起來雖然簡單,但是整個(gè)繼承體系的復(fù)用性會比較差,特別時(shí)運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的概率會非常大。

3.依賴倒轉(zhuǎn)原則(Dependence Inversion Principle,DIP)

(1)高層模塊不應(yīng)該依賴底層模塊,兩者都應(yīng)該依賴其抽象
(2)抽象不應(yīng)該依賴細(xì)節(jié)
(3)細(xì)節(jié)應(yīng)該依賴抽象

簡單說就是要求對抽象進(jìn)行編程,不要對實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合(其實(shí)依賴倒轉(zhuǎn)原則是開閉原則的具體實(shí)現(xiàn))。

4.接口隔離原則(Interface Segregation Principle,ISP)

客戶端不應(yīng)該依賴它不需要的接口。一個(gè)類對另一個(gè)類的依賴應(yīng)該建立在最小的接口上。

image.png

5.迪米特法則(Law of Demeter,LOD)(又稱最少知識原則(The Least Knowledge Principle))

只和你的直接朋友交談,不和“陌生人”交談(talk to your immediate friends and not to strangers)
其含義是:如果兩個(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)系,可以直接訪問這些對象的方法。

6.合成復(fù)用原則(Composite Reuse Principle,CRP)(又稱組合/聚合復(fù)用原則(Composition/Aggregate Reuse Principle,CARP))

含義:盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來實(shí)現(xiàn)。
通常類的復(fù)用分為繼承復(fù)用合成復(fù)用兩種。
繼承復(fù)用雖然有簡單和易實(shí)現(xiàn)的特點(diǎn),但是也有以下缺點(diǎn):
1.繼承復(fù)用破壞了類的封裝性,因?yàn)槔^承會將父類的實(shí)現(xiàn)細(xì)節(jié)暴露給子類,父類對子類是透明的,所以這種復(fù)用又稱為“白箱”復(fù)用。
2.子類與父類的耦合度高,父類實(shí)現(xiàn)的任何改變都會導(dǎo)致子類的實(shí)現(xiàn)發(fā)生變化,這不利于子類的擴(kuò)展和維護(hù)。
3.它限制了復(fù)用的靈活性,從父類繼承而來的實(shí)現(xiàn)是靜態(tài)的,在編譯時(shí)就已經(jīng)定義,所以運(yùn)行時(shí)不可能發(fā)生變化。
采用組合或者聚合復(fù)用時(shí),可以將已有對象納入到新對象中,使之成為新對象的一部分,新對象可以調(diào)用已有對象的功能,它有以下優(yōu)點(diǎn):
1.它維持了類的封裝性,因?yàn)槌煞謱ο蟮膬?nèi)部細(xì)節(jié)是新對象看不見的,所以這種復(fù)用又稱為“黑箱”復(fù)用。
2.對象間的耦合度低,可以在類的成員位置聲明抽象。
3.復(fù)用的靈活性高,這種復(fù)用可以再運(yùn)行時(shí)動態(tài)進(jìn)行,新對象可以動態(tài)地引用與成分對象類型相同的對象。

7.單一職責(zé)原則(Single Responsibility Principle,SRP)

單一職責(zé)原則(Single Responsibility Principle,SRP)又稱單一功能原則,由羅伯特·C.馬丁(Robert C. Martin)于《敏捷軟件開發(fā):原則、模式和實(shí)踐》一書中提出的。這里的職責(zé)是指類變化的原因,單一職責(zé)原則規(guī)定一個(gè)類應(yīng)該有且僅有一個(gè)引起它變化的原因,否則類應(yīng)該被拆分(There should never be more than one reason for a class to change)。

該原則提出對象不應(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é)原則的優(yōu)點(diǎn)

單一職責(zé)原則的核心就是控制類的粒度大小、將對象解耦、提高其內(nèi)聚性。如果遵循單一職責(zé)原則將有以下優(yōu)點(diǎn)。
1.降低類的復(fù)雜度。一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé),其邏輯肯定要比負(fù)責(zé)多項(xiàng)職責(zé)簡單得多。
2.提高類的可讀性。復(fù)雜性降低,自然其可讀性會提高。
3.提高系統(tǒng)的可維護(hù)性。可讀性提高,那自然更容易維護(hù)了。
4.變更引起的風(fēng)險(xiǎn)降低。變更是必然的,如果單一職責(zé)原則遵守得好,當(dāng)修改一個(gè)功能時(shí),可以顯著降低對其他功能的影響。

單一職責(zé)原則的實(shí)現(xiàn)方法

單一職責(zé)原則是最簡單但又最難運(yùn)用的原則,需要設(shè)計(jì)人員發(fā)現(xiàn)類的不同職責(zé)并將其分離,再封裝到不同的類或模塊中。而發(fā)現(xiàn)類的多重職責(zé)需要設(shè)計(jì)人員具有較強(qiáng)的分析設(shè)計(jì)能力和相關(guān)重構(gòu)經(jīng)驗(yàn)。
注意:單一職責(zé)同樣也適用于方法。一個(gè)方法應(yīng)該盡可能做好一件事情。如果一個(gè)方法處理的事情太多,其顆粒度會變得很粗,不利于重用。

關(guān)于各個(gè)原則的代碼演示請查閱如下傳送門

https://gitee.com/huiyuandev/design-patterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容