軟件設(shè)計的七大原則

軟件的可維護性和可復(fù)用性

知名軟件大師Robert C.Martin認為一個可維護性(Maintainability) 較低的軟件設(shè)計,通常由于如下4個原因造成:

  • 過于僵硬(Rigidity)
  • 過于脆弱(Fragility)
  • 復(fù)用率低(Immobility)
  • 黏度過高(Viscosity)

軟件工程和建模大師Peter Coad認為,一個好的系統(tǒng)設(shè)計應(yīng)該具備如下三個性質(zhì):

  • 可擴展性(Extensibility)
  • 靈活性(Flexibility)
  • 可插入性(Pluggability)

??軟件的復(fù)用(Reuse)或重用擁有眾多優(yōu)點,如可以提高軟件的開發(fā)效率,提高軟件質(zhì)量,節(jié)約開發(fā)成本,恰當?shù)膹?fù)用還可以改善系統(tǒng)的可維護性。面向?qū)ο笤O(shè)計復(fù)用的目標在于實現(xiàn)支持可維護性的復(fù)用。
??面向?qū)ο笤O(shè)計原則和設(shè)計模式也是對系統(tǒng)進行合理重構(gòu)的指南針,重構(gòu)(Refactoring)是在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序代碼改善軟件的質(zhì)量、性能,使其程序的設(shè)計模式和架構(gòu)更趨合理,提高軟件的擴展性和維護性。

常用的面向?qū)ο笤O(shè)計原則包括7個,這些原則并不是孤立存在的,它們相互依賴,相互補充。

  • 開閉原則(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è)計原則名稱 簡單定義
開閉原則 對擴展開放,對修改關(guān)閉
單一職責(zé)原則 一個類只負責(zé)一個功能領(lǐng)域中的相應(yīng)職責(zé)
里氏替換原則 所有引用基類的地方必須能透明地使用其子類的對象
依賴倒置原則 依賴于抽象,不能依賴于具體實現(xiàn)
接口隔離原則 類之間的依賴關(guān)系應(yīng)該建立在最小的接口上
合成/聚合復(fù)用原則 盡量使用合成/聚合,而不是通過繼承達到復(fù)用的目的
迪米特法則 一個軟件實體應(yīng)當盡可能少的與其他實體發(fā)生相互作用
  • 開閉原則(OCP)

定義

??一個軟件實體應(yīng)當對擴展開放,對修改關(guān)閉。也就是說當應(yīng)用的需求改變時,在不修改軟件實體的源代碼或者二進制代碼的前提下,可以擴展模塊的功能,使其滿足新的需求。

作用

??開閉原則是面向?qū)ο蟪绦蛟O(shè)計的終極目標,它使軟件實體擁有一定的適應(yīng)性和靈活性的同時具備穩(wěn)定性和延續(xù)性。具體來說,其作用如下:

  1. 對軟件測試的影響
    軟件遵守開閉原則的話,軟件測試時只需要對擴展的代碼進行測試就可以,因為原有的測試代碼仍然能夠正常運行。
  2. 可以提高代碼的可復(fù)用性
    粒度越小,被復(fù)用的可能性就越大;在面向?qū)ο蟮某绦蛟O(shè)計中,根據(jù)原子和抽象編程可以提高代碼的可復(fù)用性。
  3. 可以提高軟件的可維護性
    遵守開閉原則的軟件,其穩(wěn)定性高和延續(xù)性強,從而易于擴展和維護。
  • 單一職責(zé)原則(SRP)

定義

??單一職責(zé)原則規(guī)定一個類應(yīng)該有且僅有一個引起它變化的原因,否則類應(yīng)該被拆分。
該原則提出對象不應(yīng)該承擔(dān)太多職責(zé),如果一個對象承擔(dān)太多的職責(zé),至少存在以下兩個缺點:
1.一個職責(zé)的變化可能會削弱或者抑制這個類實現(xiàn)其他職責(zé)的能力;
2.當客戶端需要該對象的某一個職責(zé)時,不得不將其他不需要的職責(zé)全都包含進來,從而造成冗余代碼或代碼的浪費。

作用

??單一職責(zé)原則的核心就是控制類的粒度大小、將對象解耦、提高其內(nèi)聚性。具體來說,其作用如下:
1.降低類的復(fù)雜度。
2.提高類的可讀性。
3.提高系統(tǒng)的可維護性。
4.變更引起的風(fēng)險降低。

  • 里氏替換原則(LSP)

定義

??里氏替換原則主要闡述了有關(guān)繼承的一些原則,也就是什么時候應(yīng)該使用繼承,什么時候不應(yīng)該使用繼承,以及其中蘊含的原理。里氏替換原是繼承復(fù)用的基礎(chǔ),它反映了基類與子類之間的關(guān)系,是對開閉原則的補充,是對實現(xiàn)抽象化的具體步驟的規(guī)范。

作用

  1. 里氏替換原則是實現(xiàn)開閉原則的重要方式之一。
  2. 它克服了繼承中重寫父類造成的可復(fù)用性變差的缺點。
  3. 它是動作正確性的保證。即類的擴展不會給已有的系統(tǒng)引入新的錯誤,降低代碼出錯的可能性。
  4. 加強程序的健壯性,同時變更時可以做到非常好的兼容性,提高程序的維護性、可擴展性,降低需求變更時引入的風(fēng)險。
  • 依賴倒置原則(DIP)

定義

??高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細節(jié),細節(jié)應(yīng)該依賴抽象。其核心思想是:要面向接口編程,不要面向?qū)崿F(xiàn)編程。
??依賴倒置原則是實現(xiàn)開閉原則的重要途徑之一,它降低了客戶與實現(xiàn)模塊之間的耦合。
??由于在軟件設(shè)計中,細節(jié)具有多變性,而抽象層則相對穩(wěn)定,因此以抽象為基礎(chǔ)搭建起來的架構(gòu)要比以細節(jié)為基礎(chǔ)搭建起來的架構(gòu)要穩(wěn)定得多。這里的抽象指的是接口或者抽象類,而細節(jié)是指具體的實現(xiàn)類。
??使用接口或者抽象類的目的是制定好規(guī)范和契約,而不去涉及任何具體的操作,把展現(xiàn)細節(jié)的任務(wù)交給它們的實現(xiàn)類去完成。

作用

1.可以降低類間的耦合性。
2.可以提高系統(tǒng)的穩(wěn)定性。
3.可以減少并行開發(fā)引起的風(fēng)險。
4.可以提高代碼的可讀性和可維護性。

  • 接口隔離原則(ISP)

定義

??一個類對另一個類的依賴應(yīng)該建立在最小的接口上。也就是說要為各個類建立它們需要的專用接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調(diào)用。
接口隔離原則和單一職責(zé)都是為了提高類的內(nèi)聚性、降低它們之間的耦合性,體現(xiàn)了封裝的思想,但兩者是不同的:

  • 單一職責(zé)原則注重的是職責(zé),而接口隔離原則注重的是對接口依賴的隔離。
  • 單一職責(zé)原則主要是約束類,它針對的是程序中的實現(xiàn)和細節(jié);接口隔離原則主要約束接口,主要針對抽象和程序整體框架的構(gòu)建。

作用

1.提高系統(tǒng)的靈活性和可維護性
將臃腫龐大的接口分解為多個粒度小的接口,可以預(yù)防外來變更的擴散。
2.降低系統(tǒng)的耦合性
接口隔離提高了系統(tǒng)的內(nèi)聚性,減少了對外交互。
3.保證系統(tǒng)的穩(wěn)定性
如果接口的粒度大小定義合理,能夠保證系統(tǒng)的穩(wěn)定性;如果定義過小,則會造成接口數(shù)量過多,使設(shè)計復(fù)雜化;如果定義太大,靈活性降低,無法提供定制服務(wù),給整體項目帶來無法預(yù)料的風(fēng)險。
4.使用多個專門的接口還能夠體現(xiàn)對象的層次
因為可以通過接口的繼承,實現(xiàn)對總接口的定義。
5.能減少項目工程中的代碼冗余。
過大的大接口里面通常放置許多不用的方法,當實現(xiàn)這個接口的時候,被迫設(shè)計冗余的代碼。

  • 合成/聚合復(fù)用原則(C/ARP)

定義

??合成/聚合復(fù)用原則要求在軟件復(fù)用時,要盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實現(xiàn),其次才考慮使用繼承關(guān)系來實現(xiàn)。如果要使用繼承關(guān)系,則必須嚴格遵循里氏替換原則。合成復(fù)用原則同里氏替換原則相輔相成的,兩者都是開閉原則的具體實現(xiàn)規(guī)范。

作用

1.維持類的封裝性
因為成分對象的內(nèi)部細節(jié)是新對象看不見的,所以這種復(fù)用又稱為“黑箱”復(fù)用。
2.新舊類之間的耦合度低
這種復(fù)用所需的依賴較少,新對象存取成分對象的唯一方法是通過成分對象的接口。
3.復(fù)用的靈活性高
這種復(fù)用可以在運行時動態(tài)進行,新對象可以動態(tài)地引用與成分對象類型相同的對象。

  • 迪米特法則(LOD)/最少知識原則(LKP)

定義

??迪米特法則要求只與你的直接朋友交談,不跟“陌生人”說話。也就是說,如果兩個軟件實體無須直接通信,那么就不應(yīng)當發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。其目的是降低類之間的耦合度,提高模塊的相對獨立性。
??迪米特法則中的“朋友”是指:當前對象本身、當前對象的成員對象、當前對象所創(chuàng)建的對象、當前對象的方法參數(shù)等,這些對象同當前對象存在關(guān)聯(lián)、聚合或組合關(guān)系,可以直接訪問這些對象的方法。

作用

1.提高模塊的相對獨立性,降低類之間的耦合度。
2.親合度降低,從而提高了類的可復(fù)用率和系統(tǒng)的擴展性。

參考文章

設(shè)計模式的七大原則

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

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

  • 七大原則 原則一-- 開閉原則 原則二-- 依賴倒置原則 原則三-- 單一職責(zé)原則 原則四-- 接口隔離原則 原則...
    竹blue閱讀 288評論 1 2
  • 點關(guān)注,不迷路;持續(xù)更新Java架構(gòu)相關(guān)技術(shù)及資訊熱文?。?! 1.開閉原則 定義:一個軟件實體如類,模塊和函數(shù)應(yīng)該...
    Java_蘇先生閱讀 595評論 0 1
  • 軟件設(shè)計中,怎樣提高系統(tǒng)的可維護性和可復(fù)用性是面向?qū)ο笤O(shè)計需要解決的核心問題之一。面向?qū)ο笤O(shè)計原則是實現(xiàn)可維護性和...
    wz998閱讀 799評論 0 0
  • 1.開閉原則 一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。用抽象構(gòu)建框架,用實現(xiàn)擴展細節(jié)解釋:當我們有...
    ddxuzengbin閱讀 1,748評論 1 1
  • 1. 開閉原則 定義:一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。定義補充:用抽象構(gòu)建框架,用實現(xiàn)擴展...
    最后的輕語_dd43閱讀 7,862評論 1 7

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