【設計模式】三大原則 單一職責原則、開放-封閉原則、依賴倒轉原則

系列文章目錄


文章目錄

  • 系列文章目錄
  • 一、單一職責原則
    • 方塊游戲的設計
  • 二、開放-封閉原則
    • 原則介紹
    • 何時應對變化
  • 三、依賴倒轉原則
    • 依賴倒轉原則介紹
    • 里氏代換原則
  • 總結


在這里插入圖片描述

一、單一職責原則

單一職責原則,聽字面意思,就是說功能要單一,他的準確解釋是,就一個類而言,應該僅有一個引起他變化的原因,我們在做編程的時候,很自然的就會給一個類加各種各樣的功能,比如我們寫一個窗體應用程序,一般都會生成一個Formal這樣的類,于是我們就把各種各樣的代碼,像某種商業運算的算法,或者數據庫訪問的SQL語句什么的都寫進到這樣的類中,這就意味著,無論任何需求要來,你都需要修改這個窗體類,這其實是很糟糕的,維護麻煩,復用不可能,也缺乏靈活性。

單一職責原則:就一個類而言,應該僅有一個引起他變化的原因。

方塊游戲的設計

我們這里通過手機里的俄羅斯方塊這款游戲為例,開發這個小游戲,我們應該怎么做呢?
我們可以先建立一個窗體,然后加一個用于游戲框的控件,一個按鈕Button來控制‘開始’,最后計時器控制用于分時動畫的編程,寫代碼當然就是編寫計時器時間來繪出和刪除方塊,并做出堆積和消層的判斷,再編寫控件的鍵盤事件,如左箭頭左移,右箭頭右移等。這里我們思考,如果把所有的代碼都寫在了窗體這個java類里面,其實這樣是不合理的,因為如果這樣的話,如果要開發其他版本的俄羅斯方塊,或者是Web版或者Windows窗臺版的俄羅斯方塊,那現在這個代碼其實是不好復用的!
但這當中,有些東西是始終沒變的,比如說下落、旋轉、碰撞判斷、移動堆積這些游戲邏輯。這些都是和游戲有關的邏輯,和界面如何表示沒有什么關系,為什么要寫在一個類里面呢?如果一個類承擔的責任過多,就等于把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成的其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。 所以,我們應該找出那些是界面,那些是游戲邏輯,然后進行分離。

軟件設計真正要做的許多內容,就是發現職責并把那些職責相互分離。 其實要去判斷是否應該分離出來類,也不難,那就是如果你能夠想到多余一個的動機去改變一個類,那么這個類就具有多于一個的職責

二、開放-封閉原則

原則介紹

開放-封閉原則,是說軟件實體(類、模塊、函數等)應該可以擴展,但是不可修改

這個原則其實是有兩個特征,一個是說‘對于擴展是開放的’ , 另一個是說‘對于修改是封閉的’ 。

我們在做任何系統的時候都不要指望系統一開始時需求綁定,就再也不會變化,這是不現實也不科學的想法,需求是一直變化的,那么如何在面對需求的變化時,設計的軟件可以相對容易修改,不至于說,新需求依賴,就要把整個程序推倒重來。怎樣的設計才能面對需求的改變卻可以保持相對穩定,從而使得系統可以在第一個版本以后不斷推出新的版本呢? 開放-封閉給了我們答案。設計軟件要容易維護又不容易出問題的最好的辦法就是多擴展,少修改。

何時應對變化

開放–封閉原則的意思就是說,你設計的時候,時刻要考慮,盡量讓這個類足夠好,寫好了就不要去修改了,如果新需求來,我們增加一些類就完事了,原有的代碼能不動則不動,但是,絕對的對修改關閉是不可能的,無論模塊是多么的‘封閉’,都會存在一些無法對之封閉的變化。既然不可能完全封閉,設計人員必須對于他設計的模塊應對出哪種變化封閉做出選擇。他必須先猜測出最有可能發生的變化種類,然后構造抽象來隔離那些變化。

但是,事先猜測是很難做到的,但我們卻可以在發生小變化時,就及早去想辦法,應對發生更大變化的可能,也就是說,等到變化發生時立即采取行動,在我們最初編寫代碼時,假設變化不會發生,當變化發生時,我們就創建抽象來隔離以后發生的同類變化

我們在簡單工廠模式中,一開始只有一個加法程序,后面我們需要增加一個減法功能,我們發現,增加功能需要修改原來這個類,這就違背了今天所講到的‘開放-封閉’ 原則,于是你就該考慮重構程序,增加一個抽象的運算類,通過一些面向對象的手段,如繼承、多態等來隔離具體加法、減法與client耦合,需求依然可以滿足,還能應對變化,這時我們再加乘除法功能,就不需要再去更改client類了二十增加乘法和除法的字類就可,即面對需求,對程序的改動是通過增加新代碼進行的,而不是更改現有的代碼,這就是開放–封閉原則 的精神所在。

當然,并不是什么時候應對變化都是容易的,我們希望的是在開發工作展開不久就知道可能發生的變化,查明可能發生的變化所等待的時間越長,要創建正確的抽象就越困難。

開放封閉原則是面向對象設計的核心所在。遵循這個原則可以帶來面向對象技術所聲稱的巨大好處,也就是可維護、可擴展、可復用、靈活性好。開發人員應該僅對程序中呈現出頻繁變化的那些部分做出抽象,然而對于應用程序中的每個部分都刻意地進行抽象同樣不是一個好主意。拒絕不成熟的抽象和抽象本身一樣重要。

三、依賴倒轉原則

依賴倒轉原則介紹

依賴倒轉原則,原話解釋是抽象不應該依賴細節,細節應該依賴于抽象,說簡單點,就是要針對接口編程,不要對實現編程

依賴倒轉原則
(1)高層模塊不應該依賴低層模塊。兩個都應該依賴抽象。
(2)抽象不應該依賴細節。細節應該依賴抽象。

那么為什么要叫倒轉呢?

在面向過程開發時,為了使得常用代碼可以復用,一般都會把這些常用代碼寫成許許多多函數的程序庫,這樣我們在做新項目時,去調用這些低層的函數就可以了。比如我們做的項目大多要訪問數據庫,所以我們就把訪問數據庫的代碼寫成了函數,每次做新項目時就去調用這些函數。這也就叫做高層模塊依賴低層模塊。

其實問題也就出在這里,我們做新項目時,返現業務邏輯的高層模塊都是一樣的,但客戶卻希望使用不同的數據庫或者儲存信息方式,這時就出現麻煩了。我們希望能再次利用這些高層模塊,但高層模塊都是與低層的訪問數據庫綁定在一起的,沒辦法復用這些高層模塊。這里我們以電腦舉例,電腦里如果CPU、內存、硬盤都需要依賴具體的主板,主板一壞,所有的部件就都沒用了,這顯然不合理,反過來,如果內存壞了,也不應該造成其他部件不能用才對。而如果不管高層模塊還是低層模塊,他們都依賴于抽象,具體一點就是接口和抽象類,只要接口是穩定的,那么任何一個更改都不用擔心其他受到影響,這就使得無論高層模塊還是底層模塊都可以很容易地被復用。

如果這里還不是很理解,也是很正常的,因為還有一個設計原則,讓我們產生困惑。這個原則就叫里氏代換原則

里氏代換原則

里氏代換原則: 一個軟件實體如果使用的是一個父類的話,那么一定適用于其子類,而且它察覺不出父類對象和子類對象的區別。也就是說,在軟件里面,把父類都替換成它的子類,程序的行為沒有變化

里氏代換原則: 子類型必須能夠替換掉它們的父類型。

這里貌似是繼承需要理解的概念,子類繼承了父類,所以子類可以以父類的身份出現。
小問題:如果在面向對象設計時,一個是鳥類,一個是企鵝類,如果鳥是可以飛的,企鵝不會飛,那么企鵝是鳥嗎?企鵝可以繼承鳥這個類嗎?
其實這里是不可以的,我們討論的是面向對象設計時,也就是說,子類擁有父類所有非private的行為和屬性。鳥會飛,但是企鵝不會飛。所以這里企鵝不能以父類–鳥的身份出現,因為前提說所有鳥都可以飛,而企鵝飛不了,所以企鵝不可以繼承鳥類。
所以,只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才能真正被復用,而子類也能夠在父類的基礎上增加新的行為。

正是由于子類型的可替換性才使得使用父類類型的模塊在無須修改的情況下就可以擴展

依賴倒轉其實可以說是面向對象設計的表示,用哪種語言來編寫程序不重要,如果編寫時考慮的都是如何針對抽象編程而不是針對細節編程,即程序中所有的依賴關系都是終止于抽象類或者接口,那就是面向對象的設計,反之那就是過程化的設計了

總結

以上就是本文全部內容,本文主要向大家介紹了設計模式中的三大原則-----單一職責原則、開放-封閉原則、依賴倒轉原則。感謝各位能夠看到最后,如有問題,歡迎各位大佬在評論區指正,希望大家可以有所收獲!創作不易,希望大家多多支持!

最后,大家再見!祝好!我們下期見!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97707.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97707.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97707.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(3dnr)多幀視頻圖像去噪 (一)

一、多幀視頻圖像去噪 原理當攝像機每秒捕捉的圖像達到60FPS,除了場景切換或者一些快速運動的場 景外,視頻信號中相鄰的兩幀圖像內容大部分是相同的。并且視頻信號中的噪 聲大部分都是均值為零的隨機噪聲,因此在時間上對視頻信號做幀平均&…

從靜態到智能:用函數式接口替代傳統工具類

在 Java 早期開發中,我們習慣使用**靜態實用程序類(Utility Class)**來集中放置一些通用方法,例如驗證、字符串處理、數學計算等。這種模式雖然簡單直接,但在現代 Java 開發(尤其是 Java 8 引入 Lambda 和函…

免殺偽裝 ----> R3進程偽裝實戰(高階) ---->培養紅隊免殺思路

目錄 R3進程偽裝(免殺技術)高階技術說明 深入剖析Windows進程規避免殺技術 學習R3進程偽裝的必備技能 R3進程偽裝的核心知識點與實現步驟 核心知識點 實現步驟 免殺實現步驟 PEB與EPROCESS的深入解析 1. PEB(進程環境塊) 2. EPROCESS 3. PEB與…

深度學習——基于卷積神經網絡實現食物圖像分類(數據增強)

文章目錄 引言 一、項目概述 二、環境準備 三、數據預處理 3.1 數據增強與標準化 3.2 數據集準備 四、自定義數據集類 五、構建CNN模型 六、訓練與評估 6.1 訓練函數 6.2 評估函數 6.3 訓練流程 七、關鍵技術與優化 八、常見問題與解決 九、完整代碼 十、總結 引言 本文將詳細介…

【開題答辯全過程】以 基于微信小程序的教學輔助系統 為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人,語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

【代碼解讀】Deepseek_vl2中具體代碼調用

【代碼解讀】Deepseek_vl2中具體代碼調用 文章目錄【代碼解讀】Deepseek_vl2中具體代碼調用DeepseekVLV2Processor解讀DeepseekVLV2ForCausalLM - 多模態模型DeepSeek-VL2 Processor的輸入格式單樣本格式多樣本格式DeepSeek-VL2模型的輸出形式總結主要輸出類型:Deep…

Git 9 ,.git/index.lock 文件沖突問題( .git/index.lock‘: File exists. )

目錄 前言 一、問題背景 1.1 問題出現場景 1.2 典型報錯信息 1.3 問題影響 二、問題原因分 2.1 Git 的 index 與鎖機制 2.2 主要作用 2.3 根本原因 三、解決方案 3.1 確認進程 3.2 手動刪除 3.3 再次執行 四、注意事項 4.1 確保運行 4.2 問題排查 4.3 自動化解…

Proteus8 仿真教學全指南:從入門到實戰的電子開發利器

在電子設計、單片機課程設計或創客實踐中,你是否常因實物采購貴、新手怕燒板、調試排錯難而頭疼?Proteus8 作為一款 “全能型” EDA 仿真工具,完美解決這些痛點 —— 它集「原理圖繪制 PCB 設計 虛擬仿真」于一體,支持 51、STM3…

系統科學:結構、功能與層級探析

摘要本文旨在系統性地梳理和辨析系統科學中的核心概念——結構、功能與層級。文章首先追溯系統思想的理論源流,確立其作為一種超越還原論的整體性研究范式。在此基礎上,深度剖析系統結構的內在構成(組分、框架、動態性)、系統層級…

面試官問:你如何看待薪資待遇?

在面試過程中,“你如何看待薪資待遇?”這個問題,是很多面試官都會提出的經典問題之一。雖然表面上看起來是一個簡單的提問,但它實則關乎候選人的職業價值觀、工作態度以及對自己能力的認知。薪資是工作的重要動力之一,…

HarmonyOS 應用開發新范式:深入剖析 Stage 模型與 ArkUI 最佳實踐

好的,請看這篇基于 HarmonyOS (鴻蒙) 最新技術棧的深度技術文章。 HarmonyOS 應用開發新范式:深入剖析 Stage 模型與 ArkUI 最佳實踐 引言 隨著 HarmonyOS 4、5 的持續演進和未來 6 的規劃,其應用開發框架經歷了革命性的重構。對于技術開發者…

【Python數據可視化:Matplotlib高級技巧】

Python數據可視化:Matplotlib高級技巧引言在數據科學和分析領域,數據可視化是理解和傳達信息的關鍵工具。Python中最流行的可視化庫之一就是Matplotlib。雖然初學者可以快速上手Matplotlib的基礎功能,但掌握其高級技巧才能真正發揮這個強大庫…

LazyLLM教程 | 第7講:檢索升級實踐:親手打造“更聰明”的文檔理解系統!

本節,我們將首先介紹如何評價 RAG 的檢索組件,幫助您理解如何衡量 RAG 系統的檢索能力。隨后,我們會深入探討幾種提升 RAG 系統檢索組件效果的策略實現以及對應的效果對比:1.基于 LazyLLM 實現查詢重寫策略。2.介紹 LazyLLM 中的節…

rust語言 (1.88) egui (0.32.1) 學習筆記(逐行注釋)(二十四)窗口顏色、透明度、居中顯示

一、窗口顏色和透明度 &#xff08;一&#xff09;效果預覽&#xff08;二&#xff09;透明窗體主要代碼 use eframe::egui; use egui::Color32;fn main() -> eframe::Result<()> {let options eframe::NativeOptions {viewport: egui::ViewportBuilder::default() …

基于無人機的風電葉片全自動智能巡檢:高精度停角估計與細節優先曝光調控技術

【導讀】 本文致力于解決一個非常實際的工業問題&#xff1a;如何利用無人機&#xff08;UAV&#xff09;全自動、高效、可靠地檢查風力渦輪機葉片。葉片是風力發電機組中最昂貴且易損的部件之一&#xff0c;定期檢查至關重要。然而&#xff0c;當前的技術在自動化過程中面臨幾…

騰訊云上有性能比較強的英偉達GPU

騰訊云上有性能比較強的英偉達GPU A100&#xff0c;雖然落后3~4代&#xff0c;但是估計是最強的英偉達GPU了。

AI任務相關解決方案13-AI智能體架構方案(意圖識別+多任務規劃+MCP+RAG)與關鍵技術深度解析研究報告,以及實現代碼

文章目錄 1. 總體技術方案 2. 生成式大模型(LLM):Data Agent的大腦 3. 意圖識別:準確理解用戶意圖 3.1 基于BERT的微調方法 3.2 基于大語言模型(LLM)的零樣本/少樣本方法 4. 多任務規劃:提升架構的靈活性 4.1 任務分解與規劃 4.2 多智能體協作規劃 4.3 基于強化學習的規劃方…

每日五個pyecharts可視化圖表日歷圖和箱線圖:從入門到精通

&#x1f4ca; 本文特色&#xff1a;從零開始掌握日歷圖和箱線圖可視化技巧&#xff0c;包含多個完整實例、核心配置項解析和實用場景指南&#xff0c;助您快速構建專業數據可視化圖表。pyecharts源碼 目錄什么是日歷圖和箱線圖&#xff1f;&#x1f4c5; 日歷圖&#xff08;Ca…

在本地獲取下載chrome,然后離線搬運到 ECS

場景&#xff1a; 阿里云 ECS 無Y網&#xff0c;無法直接拉取 storage.googleapis.com。因此需先在本地里拿到直鏈并下載&#xff0c;再上傳到 ECS。 注&#xff1a; 這個鏈接是顯示近期的幾個版本 https://googlechromelabs.github.io/chrome-for-testing/ 這個鏈接是所有版…

小土堆目標檢測筆記

文章目錄1 什么是目標檢測2 目標檢測常見的數據集2.1 目標檢測數據集2.2 目標檢測數據集的標注2.3 目標檢測工具介紹3 數據集的標注3.1 VOC數據集標注3.2 加載數據集1 什么是目標檢測 希望計算機在視頻或圖像中定位并識別我們感興趣的目標 定位&#xff1a;找到目標在圖像中的…