七種常見的面向對象設計原則

来源:https://www.cnblogs.com/LXLR/p/18212389
-Advertisement-
Play Games

設計原則名稱 定義 使用頻率 單一職責原則 一個類只負責一個功能領域中的相應職責 四顆星 開閉原則 軟體實體應對擴展開發,而對修改關閉 五顆星 里氏代換原則 所有引用基類對象的地方能夠透明地使用其子類的對象 五顆星 依賴倒轉原則 抽象不應該依賴於細節,細節應該依賴於抽象 五顆星 介面隔離原則 使用多 ...


 
設計原則名稱 定義 使用頻率
單一職責原則 一個類只負責一個功能領域中的相應職責

 四顆星

開閉原則 軟體實體應對擴展開發,而對修改關閉  五顆星 
里氏代換原則 所有引用基類對象的地方能夠透明地使用其子類的對象  五顆星
依賴倒轉原則 抽象不應該依賴於細節,細節應該依賴於抽象  五顆星
介面隔離原則 使用多個專門的介面,而不使用單一的總介面  兩顆星
合成復用原則 儘量使用對象組合,而不是繼承來達到復用的目的  四顆星
迪米特法則 一個軟體實體應當儘可能少地與其他實體發生相互作用  三顆星

 

 

 

 

 

 

 

 

 

 

 

一、單一職責原則:一個類只負責一個功能領域中的相應職責

它強調一個類應該只有一個引起變化的原因。單一職責原則的使用方法:

1. 識別職責:首先,需要仔細分析類的功能,並識別出它承擔的各個職責。這些職責可以是類的功能、行為或數據操作等。

2. 分離職責:一旦識別出類的多個職責,就應該將這些職責分離到不同的類中。每個類應該只關註一個職責,並且這個職責應該被完全封裝在該類中。

3. 創建新類:對於每個分離出來的職責,可能需要創建新的類來承載它。這些新類應該具有清晰定義的介面和內部實現,以確保它們能夠獨立完成自己的職責。

4. 保持高內聚:在將職責分離到不同的類之後,要確保每個類都保持高內聚性。這意味著類內部的元素(如屬性和方法)應該緊密相關,並且共同協作以完成類的單一職責。

5. 低耦合:除了保持高內聚性外,還應該儘量減少類之間的耦合度。這可以通過使用介面、抽象類和依賴註入等技術來實現。確保類之間的依賴關係清晰且易於管理。

6. 重構現有代碼:如果現有的代碼違反了單一職責原則,應該考慮進行重構。通過重新組織代碼結構、提取方法和創建新類等方式,將職責分離並封裝到合適的類中。

遵循單一職責原則的好處包括:

* 提高代碼的可讀性和可維護性:由於每個類只關註一個職責,因此代碼結構更加清晰,易於理解和維護。
* 降低類的複雜性:通過將職責分離到不同的類中,可以降低每個類的複雜性,使其更易於測試和調試。
* 提高系統的可擴展性和靈活性:由於每個類只負責一個職責,因此可以更容易地對其進行修改和擴展,以適應新的需求或變化。

需要註意的是,單一職責原則並不是要求每個類都只能有一個方法或屬性,而是強調每個類應該有一個清晰定義的職責,並且這個職責應該被完全封裝在類中。在實際應用中,需要根據項目的具體情況和需求來靈活運用這一原則。

 

二、開閉原則:軟體實體應對擴展開發,而對修改關閉

這意味著軟體應該能夠在不修改其源代碼的情況下進行擴展。以下是開閉原則的使用方法:

1. 抽象化設計:
- 設計時,應首先識別出可能變化的點,並將這些點抽象化為介面、抽象類或基類。
- 通過定義清晰的抽象介面,我們可以確保系統的穩定性,因為具體的實現細節被隱藏在介面之後。

2. 面向介面編程:
- 在編寫代碼時,應始終依賴於抽象介面,而不是具體的實現類。
- 這樣,當需要添加新功能或修改現有功能時,我們只需要創建新的實現類,而無需修改現有的代碼。

3. 擴展而非修改:
- 當需要添加新功能時,應通過創建新的類來實現,而不是修改現有的類。
- 這意味著新的功能應該通過擴展現有系統來實現,而不是通過修改現有代碼。

4. 使用繼承和多態:
- 繼承和多態是面向對象編程的重要特性,它們可以幫助我們實現開閉原則。
- 通過繼承,我們可以創建新的子類來擴展系統的功能。
- 通過多態(重載、重寫、介面),我們可以確保系統能夠透明地使用這些子類,而無需關心具體的實現細節。

5. 遵循單一職責原則:
- 開閉原則與單一職責原則相輔相成。確保每個類只有一個職責,這樣當需要擴展或修改某個功能時,我們可以更容易地定位到相關的類。

6. 使用設計模式:
- 設計模式是實現開閉原則的有力工具。例如,工廠模式、策略模式、模板方法等都可以幫助我們在不修改現有代碼的情況下擴展系統的功能。

通過遵循開閉原則,我們可以構建出更加靈活、可維護和可擴展的軟體系統。這有助於降低系統的維護成本,提高開發效率,並使得系統能夠更好地適應未來的變化。

 

三、里氏代換原則:所有引用基類對象的地方能夠透明地使用其子類的對象

    遵循里氏代換原則,可以確保在程式中使用基類的地方可以無縫地替換為子類,而不會導致程式行為的改變。在設計過程中,應儘量從抽象類繼承,而不是從具體類繼承,以更好地利用里氏代換原則的優勢。這有助於提高程式的可靠性、可維護性和可擴展性。同時,也有助於降低代碼出錯的可能性,提高軟體的質量。

里氏代換原則的主要使用方法如下:

1. 子類擴展父類功能:子類可以擴展父類的功能,但不應改變父類原有的功能。這意味著子類在繼承父類時,除了添加新的方法實現新增功能外,應儘量避免重寫父類的方法。
2. 實現抽象方法:子類可以實現父類的抽象方法,但不應覆蓋父類的非抽象方法。這樣可以確保子類在替換父類時,不會破壞原有的程式邏輯。
3. 增加特有方法:子類中可以增加自己特有的方法,以擴展功能。
4. 註意方法重載與重寫:當子類的方法重載或重寫父類的方法時,需要特別註意方法的前置條件和後置條件。子類方法的前置條件(即輸入參數)應比父類方法更寬鬆,而後置條件(即方法返回的結果或產生的副作用)應與父類方法保持一致或更嚴格。

 

四、依賴倒轉原則:抽象不應該依賴於細節,細節應該依賴於抽象

它指導我們如何正確地消除模塊間的依賴關係,實現更加靈活和可維護的代碼結構。以下是依賴倒轉原則的使用方法:

1. 抽象化依賴:
- 依賴倒轉原則強調將模塊間的依賴關係倒置為依賴抽象類或介面,而不是具體的實現類。
- 這意味著高層模塊不應該依賴於低層模塊的具體實現,而是應該依賴於它們的抽象。

2. 使用介面和抽象類:
- 在代碼中,應儘量使用介面和抽象類來聲明變數類型、參數類型、方法返回類型等,而不是使用具體的類。
- 這樣做的好處是,當需要更換具體的實現時,只需要修改依賴的介面或抽象類的實現,而不需要修改所有使用到該具體類的代碼。

3. 避免直接依賴具體類:
- 在編寫代碼時,應儘量避免直接從具體類派生新的類,或者讓類直接依賴於具體類。
- 相反,應該通過介面或抽象類來建立依賴關係,這樣可以更加靈活地更換實現,而不需要修改大量的代碼。

4. 依賴註入:
- 依賴註入是實現依賴倒轉原則的一種常見方式。
- 通過構造函數、方法參數或屬性等方式,將依賴的介面或抽象類的具體實現註入到需要它的類中,從而實現了對具體實現的解耦。

5. 遵循里氏替換原則:
- 里氏替換原則(Liskov Substitution Principle,LSP)是依賴倒轉原則的補充。
- 它強調子類必須能夠替換其基類,並且替換後,程式的行為不會發生變化。
- 在使用繼承時,應遵循里氏替換原則,確保子類能夠正確地替換父類,並保持程式的正確性。

通過遵循依賴倒轉原則,我們可以降低模塊之間的耦合度,提高系統的可維護性和可擴展性。這使得代碼更加靈活,更容易適應需求的變化和技術的演進。同時,依賴倒轉原則也是實現開閉原則的重要手段之一,有助於我們在不修改現有代碼的情況下添加新功能或修改現有功能。

 

五、介面隔離原則:使用多個專門的介面,而不使用單一的總介面

它要求客戶端不應該依賴它不需要的介面,或者說一個類對另一個類的依賴性應當是最小的。這意味著我們應該儘量將介面細化,將大介面拆分成多個小介面,客戶端只需要知道它感興趣的方法即可。以下是介面隔離原則的使用方法:

1. 細化介面:
- 分析現有介面,識別出其中不同客戶端所需要的不同方法集合。
- 將介面拆分成多個更小的介面,每個介面只包含一組相關的方法,這些方法應該是高度內聚的。

2. 客戶端依賴最小化:
- 客戶端(即使用介面的類)應該只依賴它實際需要的介面,而不是一個包含眾多方法的龐大介面。
- 通過這種方式,客戶端的代碼將更為簡潔,並且減少了不必要的依賴。

3. 避免介面污染:
- 介面污染是指介面中包含客戶端不需要的方法,這增加了客戶端的複雜性。
- 通過細化介面,我們可以避免介面污染,確保每個介面都只為特定的客戶端提供所需的方法。

4. 使用委托或適配器:
- 在某些情況下,可能無法直接拆分介面,但可以通過委托或適配器模式來實現介面隔離。
- 委托模式允許一個對象將請求委托給另一個對象來執行,而適配器模式可以將一個類的介面轉換為客戶端所期望的另一個介面。

5. 考慮擴展性:
- 在設計介面時,應考慮到未來的擴展性。
- 儘量避免設計過於龐大或複雜的介面,因為它們可能難以維護和擴展。

6. 持續重構:
- 隨著項目的進展和需求的變化,可能需要不斷地對介面進行重構,以確保它們仍然符合介面隔離原則。
- 在重構過程中,要仔細評估每個介面的使用情況,並根據需要進行拆分或合併。

通過遵循介面隔離原則,我們可以提高代碼的可讀性、可維護性和可擴展性。它有助於減少類之間的耦合度,使得每個類都更加專註於自己的職責。同時,這也使得代碼更加靈活,更容易適應未來的變化。

 

六:合成復用原則:儘量使用對象組合,而不是繼承來達到復用的目的

它強調通過對象組合(has-a)或對象聚合(contains-a)的方式來實現代碼復用,而不是通過繼承關係。這種方式可以使系統更加靈活,降低類與類之間的耦合度,一個類的變化對其他類造成的影響相對較小。以下是合成復用原則的使用方法:

1. 識別可復用的對象:
- 在設計系統時,首先要識別出那些可以被覆用的對象或組件。這些對象或組件通常具有穩定的介面和功能,可以在多個上下文中共用。

2. 使用組合或聚合關係:
- 在新的對象或類中,通過組合或聚合關係來使用這些可復用的對象。組合關係表示“has-a”關係,即新對象包含其他對象作為其成員;聚合關係則是一種特殊的組合關係,表示整體與部分的關係。

3. 委派調用已有方法:
- 新的對象或類通過委派調用已有對象的方法來實現復用。這意味著新對象不需要重新實現已有對象的功能,而是直接利用已有對象的方法。

4. 優先使用已存在對象:
- 在創建新對象時,應優先使用已存在的對象來達到復用的目的。這有助於減少系統的開銷,並提高資源的利用率。

5. 遵循單一職責原則:
- 合成復用原則常與單一職責原則相結合使用。確保每個對象或類都只有一個職責,這樣它們更容易被覆用和組合。

6. 避免過度使用繼承:
- 繼承雖然是一種實現代碼復用的方式,但過度使用繼承可能導致系統變得僵硬和難以維護。因此,在可能的情況下,應優先考慮使用合成復用原則來替代繼承。

通過遵循合成復用原則,我們可以構建出更加靈活、可維護和可擴展的軟體系統。這有助於降低系統的維護成本,提高開發效率,並使得系統能夠更好地適應未來的變化。

 

七:迪米特原則:一個軟體實體應當儘可能少地與其他實體發生相互作用

迪米特原則,也被稱為最少知識原則(LKP),主張一個類應該對其他類有儘可能少的瞭解。為了遵循這一原則,需要確保一個對象只與它直接相關的其他對象通信。下麵是遵循迪米特原則的一些方法:

1. 限制方法可見性:只公開必須的方法,將其他方法設置為私有,這樣就能限制其他類對該類的訪問。
2. 避免使用全局變數:全局變數會使得類之間的耦合度增加,因此應儘量避免使用。
3. 謹慎使用繼承:繼承會使得子類依賴於父類,因此應謹慎使用,避免不必要的依賴。
4. 使用合成復用原則:通過組合而非繼承來複用代碼,這樣能夠降低類之間的耦合度。
5. 引入中間層:在類之間引入中間層,這樣可以降低類之間的耦合度,使得系統更易於維護。

遵循迪米特原則能夠降低類之間的耦合度,使得系統更易於維護和擴展。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • title: Vue 組件生命周期:探索鉤子 date: 2024/5/27 18:42:38 updated: 2024/5/27 18:42:38 categories: 前端開發 tags: 生命周期 非同步載入 通信原理 父子通信 兄弟通信 跨層通信 性能優化 第 1 章:介紹與背景 1.1 ...
  • 一、用途 可視區域即我們瀏覽網頁的設備肉眼可見的區域,如下圖 在日常開發中,我們經常需要判斷目標元素是否在視窗之內或者和視窗的距離小於一個值(例如 100 px),從而實現一些常用的功能,例如: 圖片的懶載入 列表的無限滾動 計算廣告元素的曝光情況 可點擊鏈接的預載入 二、實現方式 判斷一個元素是否 ...
  • 文章關註JavaScript中async/await的異常處理,指出未捕獲異常的潛在風險。1)使用try-catch,雖全面但冗餘;2)藉助Promise的catch,減少冗餘; 3) 利用await-to-js庫簡化異常處理 ...
  • 大家看過黑客帝國的代碼雨嗎?本人自己寫了一個,效果還可以。演示效果請見https://www.lanbaoshi.site/coderain.htm 下麵上代碼: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
  • title: Vue.js條件渲染與列表渲染指南 date: 2024/5/26 20:11:49 updated: 2024/5/26 20:11:49 categories: 前端開發 tags: VueJS 前端開發 數據綁定 列表渲染 狀態管理 路由配置 性能優化 第1章:Vue.js基礎與 ...
  • 從Vue開始較大範圍在前端應用開始,關於Vue一些基礎知識的討論和麵試問題就在開發圈子裡基本上就跟前幾年的股票和基金一樣,樓下擺攤賣醬香餅的阿姨都能說上幾句那種。找過前端開發工作或者正在找開發工作的前端都知道,面試官基本上都有那麼幾個常問的問題,而網上呢也有那麼一套可以用來背誦的“八股文”,自己懂多 ...
  • title: Vue 3指令與事件處理 date: 2024/5/25 18:53:37 updated: 2024/5/25 18:53:37 categories: 前端開發 tags: Vue3基礎 指令詳解 事件處理 高級事件 實戰案例 最佳實踐 性能優化 第1章 Vue 3基礎 1.1 V ...
  • Symbol 引用 iconfont icon圖標庫 Symbol 引用 這是一種全新的使用方式,應該說這才是未來的主流,也是平臺目前推薦的用法。相關介紹可以參考這篇文章 這種用法其實是做了一個 SVG 的集合,與另外兩種相比具有如下特點: 支持多色圖標了,不再受單色限制。 通過一些技巧,支持像字體 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...