設(shè)計(jì)模式01-軟件設(shè)計(jì)七大原則

寫在前面

  • 軟件設(shè)計(jì)七大原則
    • 開閉原則
    • 里氏替換原則
    • 依賴倒置原則
    • 單一職責(zé)原則
    • 接口隔離原則
    • 迪米特法則
    • 合成復(fù)用原則
  • 創(chuàng)建型模式
    • 單例(Singleton)模式
    • 原型(Prototype)模式
    • 簡(jiǎn)單工廠(Simple Factory)模式
    • 工廠方法(Factory Method)模式
    • 抽象工廠(Abstract Factory)模式
    • 建造者(Builder)模式
  • 結(jié)構(gòu)型模式
    • 代理(Proxy)模式
    • 適配器(Adapter)模式
    • 橋接(Bridge)模式
    • 裝飾(Decorator)模式
    • 外觀(Facade)模式
    • 享元(Flyweight)模式
    • 組合(Composite)模式
  • 行為型模式
    • 模板方法(Template Method)模式
    • 策略(Strategy)模式
    • 命令(Command)模式
    • 職責(zé)鏈(Chain of Responsibility)模式
    • 狀態(tài)(State)模式
    • 觀察者(Observer)模式
    • 中介者(Mediator)模式
    • 迭代器(Iterator)模式
    • 訪問者(Visitor)模式
    • 備忘錄(Memento)模式
    • 解釋器(Interpreter)模式

本系列共四篇筆記分別如下:

開閉原則

定義: 軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

作用:

  1. 對(duì)軟件測(cè)試的影響:軟件遵守開閉原則的話,軟件測(cè)試時(shí)只需要對(duì)擴(kuò)展的代碼進(jìn)行測(cè)試就可以了,因?yàn)樵械臏y(cè)試代碼仍然能夠正常運(yùn)行。
  2. 可以提高代碼的可復(fù)用性:粒度越小,被復(fù)用的可能性就越大;在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,根據(jù)原子和抽象編程可以提高代碼的可復(fù)用性。
  3. 可以提高軟件的可維護(hù)性:遵守開閉原則的軟件,其穩(wěn)定性高和延續(xù)性強(qiáng),從而易于擴(kuò)展和維護(hù)。

實(shí)現(xiàn):

可以通過“抽象約束、封裝變化”來(lái)實(shí)現(xiàn)開閉原則,即通過接口或者抽象類為軟件實(shí)體定義一個(gè)相對(duì)穩(wěn)定的抽象層,而將相同的可變因素封裝在相同的具體實(shí)現(xiàn)類中。

里氏替換原則

定義: 繼承必須確保超類所擁有的性質(zhì)在子類中仍然成立。(通俗來(lái)講:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。也可以說(shuō):子類繼承父類時(shí),除添加新的方法完成新增功能外,盡量不要重寫父類的方法。)

作用:

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

實(shí)現(xiàn):

  1. 子類可以實(shí)現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法
  2. 子類中可以增加自己特有的方法
  3. 當(dāng)子類的方法重載父類的方法時(shí),方法的前置條件(即方法的輸入?yún)?shù))要比父類的方法更寬松
  4. 當(dāng)子類的方法實(shí)現(xiàn)父類的方法時(shí)(重寫/重載或?qū)崿F(xiàn)抽象方法),方法的后置條件(即方法的的輸出/返回值)要比父類的方法更嚴(yán)格或相等

依賴倒置原則

定義: 高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴抽象。其核心思想是:要面向接口編程,不要面向?qū)崿F(xiàn)編程。

作用:

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

實(shí)現(xiàn):

  1. 每個(gè)類盡量提供接口或抽象類,或者兩者都具備。
  2. 變量的聲明類型盡量是接口或者是抽象類。
  3. 任何類都不應(yīng)該從具體類派生。
  4. 使用繼承時(shí)盡量遵循里氏替換原則。

單一職責(zé)原則

定義: 這里的職責(zé)是指類變化的原因,單一職責(zé)原則規(guī)定一個(gè)類應(yīng)該有且僅有一個(gè)引起它變化的原因,否則類應(yīng)該被拆分。

作用:

單一職責(zé)原則的核心就是控制類的粒度大小、將對(duì)象解耦、提高其內(nèi)聚性。如果遵循單一職責(zé)原則將有以下優(yōu)點(diǎn)。

  1. 降低類的復(fù)雜度。一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé),其邏輯肯定要比負(fù)責(zé)多項(xiàng)職責(zé)簡(jiǎn)單得多。
  2. 提高類的可讀性。復(fù)雜性降低,自然其可讀性會(huì)提高。
  3. 提高系統(tǒng)的可維護(hù)性??勺x性提高,那自然更容易維護(hù)了。
    變更引起的風(fēng)險(xiǎn)降低。變更是必然的,如果單一職責(zé)原則遵守得好,當(dāng)修改一個(gè)功能時(shí),可以顯著降低對(duì)其他功能的影響。

實(shí)現(xiàn):

單一職責(zé)原則是最簡(jiǎn)單但又最難運(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)。

接口隔離原則

定義: 客戶端不應(yīng)該被迫依賴于它不使用的方法 。該原則還有另外一個(gè)定義:一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上。

以上兩個(gè)定義的含義是:要為各個(gè)類建立它們需要的專用接口,而不要試圖去建立一個(gè)很龐大的接口供所有依賴它的類去調(diào)用。

作用:

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

實(shí)現(xiàn):

  1. 接口盡量小,但是要有限度。一個(gè)接口只服務(wù)于一個(gè)子模塊或業(yè)務(wù)邏輯。
  2. 為依賴接口的類定制服務(wù)。只提供調(diào)用者需要的方法,屏蔽不需要的方法。
  3. 了解環(huán)境,拒絕盲從。每個(gè)項(xiàng)目或產(chǎn)品都有選定的環(huán)境因素,環(huán)境不同,接口拆分的標(biāo)準(zhǔn)就不同深入了解業(yè)務(wù)邏輯。
  4. 提高內(nèi)聚,減少對(duì)外交互。使接口用最少的方法去完成最多的事情。

迪米特法則

定義: 又叫作最少知識(shí)原則。只與你的直接朋友交談,不跟“陌生人”說(shuō)話。其含義是:如果兩個(gè)軟件實(shí)體無(wú)須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。其目的是降低類之間的耦合度,提高模塊的相對(duì)獨(dú)立性。

作用:

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

但是,過度使用迪米特法則會(huì)使系統(tǒng)產(chǎn)生大量的中介類,從而增加系統(tǒng)的復(fù)雜性,使模塊之間的通信效率降低。所以,在釆用迪米特法則時(shí)需要反復(fù)權(quán)衡,確保高內(nèi)聚和低耦合的同時(shí),保證系統(tǒng)的結(jié)構(gòu)清晰。

實(shí)現(xiàn):

  1. 在類的劃分上,應(yīng)該創(chuàng)建弱耦合的類。類與類之間的耦合越弱,就越有利于實(shí)現(xiàn)可復(fù)用的目標(biāo)。
  2. 在類的結(jié)構(gòu)設(shè)計(jì)上,盡量降低類成員的訪問權(quán)限。
  3. 在類的設(shè)計(jì)上,優(yōu)先考慮將一個(gè)類設(shè)置成不變類。
  4. 在對(duì)其他類的引用上,將引用其他對(duì)象的次數(shù)降到最低。
  5. 不暴露類的屬性成員,而應(yīng)該提供相應(yīng)的訪問器(set 和 get 方法)。
  6. 謹(jǐn)慎使用序列化(Serializable)功能。

合成復(fù)用原則

定義: 也叫組合/聚合復(fù)用原則。它要求在軟件復(fù)用時(shí),要盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來(lái)實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來(lái)實(shí)現(xiàn)。

如果要使用繼承關(guān)系,則必須嚴(yán)格遵循里氏替換原則。合成復(fù)用原則同里氏替換原則相輔相成的,兩者都是開閉原則的具體實(shí)現(xiàn)規(guī)范。

作用:

通常類的復(fù)用分為繼承復(fù)用和合成復(fù)用兩種,繼承復(fù)用雖然有簡(jiǎn)單和易實(shí)現(xiàn)的優(yōu)點(diǎn),但它也存在以下缺點(diǎn)。

  1. 繼承復(fù)用破壞了類的封裝性。因?yàn)槔^承會(huì)將父類的實(shí)現(xiàn)細(xì)節(jié)暴露給子類,父類對(duì)子類是透明的,所以這種復(fù)用又稱為“白箱”復(fù)用。
  2. 子類與父類的耦合度高。父類的實(shí)現(xiàn)的任何改變都會(huì)導(dǎo)致子類的實(shí)現(xiàn)發(fā)生變化,這不利于類的擴(kuò)展與維護(hù)。
  3. 它限制了復(fù)用的靈活性。從父類繼承而來(lái)的實(shí)現(xiàn)是靜態(tài)的,在編譯時(shí)已經(jīng)定義,所以在運(yùn)行時(shí)不可能發(fā)生變化。

采用組合或聚合復(fù)用時(shí),可以將已有對(duì)象納入新對(duì)象中,使之成為新對(duì)象的一部分,新對(duì)象可以調(diào)用已有對(duì)象的功能,它有以下優(yōu)點(diǎn)。

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

實(shí)現(xiàn):

合成復(fù)用原則是通過將已有的對(duì)象納入新對(duì)象中,作為新對(duì)象的成員對(duì)象來(lái)實(shí)現(xiàn)的,新對(duì)象可以調(diào)用已有對(duì)象的功能,從而達(dá)到復(fù)用。

總結(jié)

設(shè)計(jì)原則 一句話歸納 目的
開閉原則 對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉 降低維護(hù)帶來(lái)的新風(fēng)險(xiǎn)
依賴倒置原則 高層不應(yīng)該依賴低層,要面向接口編程 更利于代碼結(jié)構(gòu)的升級(jí)擴(kuò)展
單一職責(zé)原則 一個(gè)類只干一件事,實(shí)現(xiàn)類要單一 便于理解,提高代碼的可讀性
接口隔離原則 一個(gè)接口只干一件事,接口要精簡(jiǎn)單一 功能解耦,高聚合、低耦合
迪米特法則 不該知道的不要知道,一個(gè)類應(yīng)該保持對(duì)其它對(duì)象最少的了解,降低耦合度 只和朋友交流,不和陌生人說(shuō)話,減少代碼臃腫
里氏替換原則 不要破壞繼承體系,子類重寫方法功能發(fā)生改變,不應(yīng)該影響父類方法的含義 防止繼承泛濫
合成復(fù)用原則 盡量使用組合或者聚合關(guān)系實(shí)現(xiàn)代碼復(fù)用,少使用繼承 降低代碼耦合

參考資料

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

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

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

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