六大設(shè)計原則

1.單一職責(zé)原則

定義
單一職責(zé)原則(SRP:Single responsibility principle)又稱單一功能原則。它規(guī)定一個類應(yīng)該只有一個發(fā)生變化的原因。
特點
1 降低類的復(fù)雜性, 對類或接口的職責(zé)有清晰明確定義
2 提高可讀性
3 提高可維護性
4 降低變更引起的風(fēng)險, 接口改變只影響相應(yīng)的實現(xiàn)類, 不影響其他類

重點
接口一定要做到單一職責(zé);
類的單一職責(zé)比較難以實現(xiàn), 盡量做到只有一個原因引起變化;
一個方法盡可能做一件事, 能分解就分解, 分解到原子級別;

單一職責(zé)原則.png

2.里氏替換原則

定義
所有 引用基類的地方 必須能 透明地使用其子類的對象;
通俗點講:只要 父類出現(xiàn)的地方子類就可以出現(xiàn), 替換為子類也不會產(chǎn)生任何錯誤, 使用者不需要知道父類還是子類;(策略模式)

需求
玩家玩射擊氣球游戲,他既能使用AK仿真槍,也可以使用步槍還可以使用手槍射擊氣球。

優(yōu)缺點
里氏替換原則核心是繼承,同樣它的優(yōu)缺點也是繼承的優(yōu)缺點
繼承的優(yōu)點

  • 1 代碼共享 : 共享代碼, 子類都擁有父類的方法和屬性, 將 父類的代碼共享給了子類;
  • 2 重用性 : 提高代碼的重用性, 子類重用父類的代碼;
  • 3 子父類異同 : 子類形似父類, 異于父類, 父子都不同;
  • 4 擴展性 : 提高代碼的可擴展性, 子類就可以為所欲為了, 子類可以隨意擴展父類;
  • 5 開放性 : 提高產(chǎn)品或項目的開放性, 父類隨意擴展, 開放性隨之增加了;
    繼承缺點
  • 1 侵入性 : 繼承是侵入性的, 子類 強制繼承 父類的方法和屬性;
  • 2 靈活性 : 降低代碼的靈活性, 子類必須擁有父類的屬性和方法, 子類收到了父類的約束, 這是從子類的角度講得;
  • 3 耦合性 : 增強了耦合性, 父類的屬性和方法被修改時, 還需要顧及其子類, 可能會帶來大量的重構(gòu), 這是從父類的角度講的;

優(yōu)點:將子類單獨作為一個業(yè)務(wù)來使用, 會讓代碼間的耦合關(guān)系都復(fù)雜, 缺乏類替換標(biāo)準(zhǔn)
缺點 將子類當(dāng)做父類用, 抹殺了子類的個性;

重點

  • 返回值: 父類方法返回值類型 F, 子類方法返回值類型 S, 里氏替換原則是 S 范圍必須小于 F;
  • 重載: 父類 子類 方法參數(shù)類型或者數(shù)量不同, 如果要符合里氏替換要求的話, 子類參數(shù)必須 >= 父類參數(shù), 即不能讓子類自己定義的方法被調(diào)用;
里氏替換原則.png

3.依賴倒置原則

定義
細節(jié)依賴抽象 : 高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細節(jié);細節(jié)應(yīng)該依賴抽象。(依賴就是值引用)
抽象就是接口和抽象類
細節(jié)就是具體的實現(xiàn)類

問題由來
類A直接依賴類B,假如要將類A改為依賴類C,則必須通過修改類A的代碼來達成。這種場景下,類A一般是高層模塊,負責(zé)復(fù)雜的業(yè)務(wù)邏輯;類B和類C是低層模塊,負責(zé)基本的原子操作;假如修改類A,會給程序帶來不必要的風(fēng)險。
解決辦法
將類A修改為依賴接口I,類B和類C各自實現(xiàn)接口I,類A通過接口I間接與類B或者類C發(fā)生聯(lián)系,則會大大降低修改類A的幾率。

依賴倒置好處
減少類之間的耦合
提高系統(tǒng)穩(wěn)定性
降低并發(fā)風(fēng)險
提高代碼可讀性

依賴倒置注入實現(xiàn)

  • 構(gòu)造函數(shù)依賴對象
    注入方法 : 通過 構(gòu)造函數(shù)參數(shù) 聲明依賴對象, 即構(gòu)造函數(shù)注入;

  • Setter 方法依賴對象
    通過 Setter 函數(shù) 參數(shù) 聲明依賴對象, 即構(gòu)造函數(shù)注入;

  • 接口注入依賴對象
    在接口方法的參數(shù)中聲明依賴對象, 即接口注入;

依賴倒置本質(zhì)
通過 抽象 即 接口或者抽象類, 使 各個類 和 模塊實現(xiàn)彼此獨立, 實現(xiàn)模塊間 松耦合;

注意點
盡量不要覆蓋方法, 如果方法在抽象類中已經(jīng)實現(xiàn), 子類不要覆蓋;

使用場景
依賴倒置在小項目中得有點很難體現(xiàn)出來, 是否采用依賴倒置原則影響不大;
項目越大, 需求改變越多, 采用依賴倒置原則設(shè)計的接口或抽象類 對 實現(xiàn)類的約束, 會大大減少維護成本

例子:媽媽講故事

4.接口隔離原則

定義
接口隔離定義 : 建立單一的接口, 功能盡量細化, 不要建立臃腫的接口;

  • 不需要的接口 : 客戶端盡量不依賴其不需要的接口, 客戶端需要什么接口就提供什么接口, 剔除不需要的接口, 對接口進行細化, 保持接口方法最少;
  • 最小接口 : 類間的依賴關(guān)系應(yīng)該建立在最小接口上, 細化接口;

單一職責(zé) 與 接口隔離 區(qū)別 :

  • 單一原則 注重職責(zé), 注重業(yè)務(wù)邏輯上得劃分;
  • 接口隔離 注重的是接口的方法盡量少

特點

  • 接口盡量小
    拆分接口 : 接口隔離的核心定義, 不出現(xiàn)臃腫的接口;
  • 接口高內(nèi)聚
    高內(nèi)聚 : 提高接口, 類, 模塊的處理能力, 減少對外界交互;
    具體方法 : 接口中盡量少公布public 方法, 對外公布的 public 方法越少, 變更的風(fēng)險就越小, 有利于后期的維護;

定制服務(wù)
起源 : 系統(tǒng)模塊間的耦合需要有相互訪問的接口, 這里就需要為各個 客戶端 的訪問提供定制的服務(wù)接口;
要求 : 只提供訪問者需要的方法, 不需要的就不提供;

接口隔離限度

  • 粒度小 : 接口粒度越小, 系統(tǒng)越靈活, 但是同時使系統(tǒng)結(jié)構(gòu)復(fù)雜, 開發(fā)難度增加, 降低了系統(tǒng)的可維護性;
  • 粒度大 : 靈活性降低, 無法提供定制服務(wù), 增大項目風(fēng)險;

原子接口劃分原則

  • 接口模塊對應(yīng)關(guān)系 : 一個接口只服務(wù)于一個子模塊 或 業(yè)務(wù)邏輯;
  • 方法壓縮 : 通過業(yè)務(wù)邏輯, 壓縮接口中得 public 方法, 減少接口的方法的數(shù)量;
  • 修改適配 : 盡量去修改已經(jīng)污染的接口, 如果變更風(fēng)險較大, 采用適配器模式進行轉(zhuǎn)化處理;

例子:
Activity的OnclickListener和OnLongClickListener單獨分開。

5.迪米特法則

定義
最少知識原則, 一個對象應(yīng)該對其它對象有最少的了解, 即一個類對自己需要耦合或者調(diào)用的類知道的最少;

生活示例看代碼
朋友間必須保持距離
距離太近示例 : 朋友間不能無話不說, 無所不知, 類 A 與 B 耦合, B 將很多方法暴露給 A, 兩個類之間的的耦合關(guān)系非常牢固, 這明顯違反設(shè)計原則;

保持距離方法 : 將 類 B 暴露給 A 的方法封裝, 暴露的方法越少越好, 類 B 高內(nèi)聚, 與 A 低耦合;

設(shè)計方法 : 一個類的 public 方法越多, 修改時涉及的范圍也就越大, 變更引起的風(fēng)險也就越大, 在系統(tǒng)設(shè)計時要注意, 能用 private 就用private , 能用 protected 就用 protected, 能少用 public 就少用 public, 能加上 final 就加上 final;

優(yōu)缺點

  • 優(yōu)點: 類間解耦, 弱耦合, 耦合降低, 復(fù)用率提高;
  • 缺點、; 類間的耦合性太低, 會產(chǎn)生大量的中轉(zhuǎn)或跳轉(zhuǎn)類, 會導(dǎo)致系統(tǒng)的復(fù)雜性提高, 加大維護難度;

例子:
媽媽講故事,媽媽依賴書,后來,書需要修改,又依賴媽媽。兩個類互相耦合了。暴露給其他對象的方法,盡量簡單,對方只管使用就可以,不需要知道里面具體是怎么執(zhí)行的。如果對方都知道了,就不安全。

6.開閉原則

定義
軟件的實體類, 模塊, 函數(shù) 應(yīng)該對擴展開放, 對修改關(guān)閉; 即軟件實體應(yīng)該通過擴展實現(xiàn)變化, 不是通過修改已有的代碼實現(xiàn)變化;

優(yōu)點

  • 利于測試 :
    如果改變軟件內(nèi)容, 需要將所有的測試流程都執(zhí)行一遍, 如 單元測試, 功能測試, 集成測試等, 如果只是擴展, 只單獨測試擴展部分即可;

  • 提高復(fù)用性 :
    所有邏輯都從原子邏輯組合, 原子邏輯粒度越小, 復(fù)用性越大; 這樣避免相同邏輯存在, 修改時需要修改多個此相同邏輯;

  • 提高可維護性 :
    維護一個類最好的方式是 擴展一個類, 而不是修改一個類, 如果需要修改需要讀懂源碼才能修改, 擴展的話只需要了解即可, 直接繼承擴展;

總結(jié)

思想:
抽象 單一 最小化

方法:
面向接口編程

達到目標(biāo):

  • 高擴展性
  • 高內(nèi)聚
  • 低耦合
最后編輯于
?著作權(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)容

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