Java設計模式是什么?核心設計原則有哪些?

文章目錄

  • 什么是設計模式?
  • 為什么使用設計模式?
  • 設計模式的核心設計原則是什么?
    • 1. 開閉原則(Open-Closed Principle, OCP)
    • 2. 里氏替換原則(Liskov Substitution Principle, LSP)
    • 3. 依賴倒置原則(Dependency Inversion Principle, DIP)
    • 4. 單一職責原則(Single Responsibility Principle, SRP)
    • 5. 接口隔離原則(Interface Segregation Principle, ISP)
    • 6. 迪米特法則(Law of Demeter, LoD)
    • 7. 合成/聚合復用原則(Composite Reuse Principle, CRP)
    • 七大原則的核心價值總結
  • 常見的設計模式有哪些?

作為一個Java開發程序員,設計模式就像是習武之人的內功心法,直接少走20年彎路,其重要性顯而易見。通過掌握7大設計原則、23種設計模式,可以編寫出 高內聚、低耦合、易擴展、易維護 的高質量代碼,應對復雜軟件系統的設計。

什么是設計模式?

  • 設計模式,是一套被反復使用、多數人知曉的、經過分類編目的代碼設計經驗的總結。

  • 他描述了在軟件設計過程中的一些不斷重復出現的問題,以及該問題的解決方案。也就是說,他是解決特定問題的一系列套路,是前輩們的代碼設計經驗的總結,具有一定的普遍性,可以反復使用。


為什么使用設計模式?

  • 設計模式的本質是面向對象設計原則的實際運用,是對類的封裝性、繼承性和多態性以及類的關聯關系和組合關系的充分理解。
  • 正確使用設計模式具有以下優點:
    • 可以提高程序員的思維能力、編程能力和設計能來。
    • 使程序設計更加標準化、代碼編程更加工程化,使軟件開發效率大大提高,從而縮短軟件開發的周期。
    • 使設計的代碼可重用性高、可讀性強、可靠性高、靈活性好、可維護性強。

設計模式的核心設計原則是什么?

1. 開閉原則(Open-Closed Principle, OCP)

  • 定義:軟件實體(類、模塊、函數等)應對 擴展開放,對 修改關閉

    • 擴展開放:通過新增代碼(如新類、新模塊)來實現功能擴展。
    • 修改關閉:不修改已有代碼即可滿足新需求。
  • 核心思想

    • 抽象約束:通過接口或抽象類構建穩定的抽象層,隔離變化點。
    • 封裝變化:將可變因素封裝在具體實現類中,需求變更時只需新增或調整實現類。
  • 示例

    // 抽象接口(穩定層)
    interface Shape {void draw();
    }// 具體實現類(可擴展)
    class Circle implements Shape {public void draw() {System.out.println("Drawing Circle");}
    }class Rectangle implements Shape {public void draw() {System.out.println("Drawing Rectangle");}
    }// 客戶端代碼(無需修改)
    public class Main {public static void main(String[] args) {Shape shape = new Circle();shape.draw(); // 輸出:Drawing Circle}
    }
    
  • 好處

    • 降低維護成本:無需修改已有代碼,減少引入新錯誤的風險。
    • 提高擴展性:通過新增實現類即可支持新功能(如新增 Triangle 類)。
    • 增強穩定性:抽象層保持不變,系統架構更穩定。

2. 里氏替換原則(Liskov Substitution Principle, LSP)

  • 定義:所有引用基類的地方必須能透明地使用其子類的對象。

    • 子類替換父類:子類對象應能完全替代父類對象,且程序行為和結果不受影響。
  • 核心思想

    • 行為一致性:子類應繼承父類的契約,不破壞父類定義的規范。
    • 避免副作用:子類不應強制改變父類的行為預期。
  • 示例

    // 父類
    abstract class Vehicle {abstract void start();
    }// 子類(符合 LSP)
    class Car extends Vehicle {public void start() {System.out.println("Car starts");}
    }// 錯誤示例(違反 LSP)
    class BrokenCar extends Vehicle {public void start() {System.out.println("Car explodes"); // 破壞父類行為預期}
    }
    
  • 好處

    • 代碼復用性:子類可安全復用父類邏輯。
    • 可靠性:程序行為更可預測,避免因子類錯誤導致異常。
    • 解耦:高層模塊無需關注具體子類實現。

3. 依賴倒置原則(Dependency Inversion Principle, DIP)

  • 定義

    • 高層模塊不應該依賴低層模塊,二者都應該依賴 抽象
    • 抽象不應該依賴細節,細節應該依賴抽象。
  • 核心思想

    • 面向接口編程:通過抽象(接口或抽象類)解耦模塊間的依賴關系。
    • 減少耦合:高層模塊不直接依賴底層實現,而是通過抽象接口間接調用。
  • 示例

    // 抽象接口(高層依賴)
    interface Database {void save();
    }// 具體實現(低層模塊)
    class MySQL implements Database {public void save() {System.out.println("Saving to MySQL");}
    }// 高層模塊(依賴抽象)
    class UserService {private Database database;public UserService(Database database) {this.database = database;}public void saveUser() {database.save();}
    }
    
  • 好處

    • 靈活性:可輕松切換底層實現(如從 MySQL 改為 PostgreSQL)。
    • 測試性:通過 Mock 抽象接口,方便單元測試。
    • 解耦:模塊間依賴關系更清晰,降低維護成本。

4. 單一職責原則(Single Responsibility Principle, SRP)

  • 定義:一個類應該只有一個引起它變化的原因。

    • 職責分離:一個類只負責一項功能,避免功能耦合。
  • 核心思想

    • 高內聚:將相關功能集中在一個類中。
    • 低耦合:不同職責分離到獨立類中,減少相互影響。
  • 示例

    // 錯誤示例(違反 SRP)
    class User {private String name;private String email;// 職責1:用戶信息管理public void setName(String name) { this.name = name; }// 職責2:郵件發送public void sendEmail(String message) {System.out.println("Sending email to " + email + ": " + message);}
    }// 改進方案(職責分離)
    class User {private String name;private String email;public void setName(String name) { this.name = name; }
    }class EmailService {public void sendEmail(String email, String message) {System.out.println("Sending email to " + email + ": " + message);}
    }
    
  • 好處

    • 易維護:修改一個功能時,不會影響其他職責。
    • 復用性:單一職責的類更容易被其他模塊復用。
    • 可測試性:職責清晰的類更易編寫單元測試。

5. 接口隔離原則(Interface Segregation Principle, ISP)

  • 定義:客戶端不應該依賴它不需要的接口。

    • 接口小型化:提供多個細粒度的接口,避免“胖接口”。
  • 核心思想

    • 按需依賴:客戶端僅依賴其實際需要的方法。
    • 避免冗余:減少接口中不必要方法的暴露。
  • 示例

    // 錯誤示例(“胖”接口)
    interface Animal {void eat();     // 所有動物都需要void fly();     // 僅鳥類需要void swim();    // 僅魚類需要
    }// 改進方案(接口隔離)
    interface Eatable {void eat();
    }interface Flyable {void fly();
    }interface Swimmable {void swim();
    }class Bird implements Eatable, Flyable {public void eat() { System.out.println("Bird eats"); }public void fly() { System.out.println("Bird flies"); }
    }class Fish implements Eatable, Swimmable {public void eat() { System.out.println("Fish eats"); }public void swim() { System.out.println("Fish swims"); }
    }
    
  • 好處

    • 減少依賴:客戶端僅需關注所需接口。
    • 靈活性:接口組合更靈活,適應不同需求。
    • 可擴展性:新增功能時,只需擴展特定接口。

6. 迪米特法則(Law of Demeter, LoD)

  • 定義:一個對象應盡可能少地了解其他對象。

    • 最少知識原則:只與直接朋友通信,避免跨層依賴。
  • 核心思想

    • 降低耦合:對象之間交互僅限于必要的依賴。
    • 封裝細節:隱藏內部實現,通過接口暴露行為。
  • 示例

    // 錯誤示例(違反 LoD)
    class Manager {public void manage(Employee employee) {System.out.println("Manager manages employee: " + employee.getName());}
    }class Employee {private String name;public String getName() { return name; }
    }class Client {public void doWork() {Employee employee = new Employee();Manager manager = new Manager();manager.manage(employee); // 正確:Manager 直接依賴 Employee}
    }// 更復雜的錯誤示例(跨層依賴)
    class Client {public void doWork() {Department department = new Department();Employee employee = department.getEmployee(0);Manager manager = new Manager();manager.manage(employee); // 錯誤:Client 間接依賴 Employee}
    }
    
  • 好處

    • 松耦合:模塊間依賴更清晰,減少連鎖修改。
    • 可維護性:代碼結構更簡潔,易于理解和調試。
    • 穩定性:減少因依賴變更導致的連鎖反應。

7. 合成/聚合復用原則(Composite Reuse Principle, CRP)

  • 定義:盡量使用 對象組合/聚合,而不是繼承來達到復用目的。

    • 組合優先于繼承:通過組合實現功能擴展,避免繼承的強耦合。
  • 核心思想

    • 靈活性:組合允許動態替換實現,繼承是靜態的。
    • 減少繼承層級:避免多層繼承導致的復雜性和脆弱性。
  • 示例

    // 錯誤示例(繼承)
    class Car {void start() { System.out.println("Car starts"); }
    }class SportsCar extends Car {void start() { System.out.println("SportsCar starts with V8 engine"); }
    }// 改進方案(組合)
    interface Engine {void start();
    }class V8Engine implements Engine {public void start() { System.out.println("V8 Engine starts"); }
    }class Car {private Engine engine;public Car(Engine engine) {this.engine = engine;}void start() {engine.start(); // 通過組合調用}
    }
    
  • 好處

    • 靈活性:可動態切換實現(如 Car 支持多種 Engine)。
    • 降低耦合:避免繼承導致的強依賴關系。
    • 代碼復用性:通過組合復用多個獨立組件。

七大原則的核心價值總結

原則名稱核心目標關鍵實踐
開閉原則對擴展開放,對修改關閉抽象層封裝變化
里氏替換子類替換父類不影響程序行為遵循父類契約
依賴倒置高層依賴抽象,低層實現細節面向接口編程
單一職責一個類只負責一項職責職責分離,高內聚
接口隔離提供最小接口,避免冗余細粒度接口,按需依賴
迪米特法則減少對象間直接交互封裝細節,最少知識
合成復用優先組合而非繼承通過組合實現靈活擴展

常見的設計模式有哪些?

設計模式類型設計模式名稱核心作用適用場景
創建型單例模式保證唯一實例資源管理、全局訪問
創建型工廠方法解耦對象創建動態選擇實現
創建型抽象工廠創建相關對象族跨平臺UI、產品族生成
創建型建造者分階段構建復雜對象配置復雜對象
創建型原型復制現有對象高性能對象創建
結構型適配器兼容接口集成遺留系統
結構型裝飾器動態擴展功能功能組合
結構型代理控制訪問權限控制、延遲加載
結構型組合樹形結構文件系統、菜單
結構型橋接解耦抽象與實現多維變化系統
結構型外觀簡化接口復雜系統簡化
結構型享元共享對象內存優化
行為型策略動態切換算法支付方式、排序算法
行為型觀察者事件通知消息訂閱、GUI事件
行為型命令封裝請求撤銷/重做、任務隊列
行為型模板方法定義算法骨架測試框架、流程固定
行為型迭代器遍歷集合統一訪問不同數據結構
行為型責任鏈傳遞請求審批流程、過濾器鏈
行為型備忘錄恢復狀態撤銷操作、狀態快照
行為型狀態狀態驅動行為訂單狀態機、游戲狀態
行為型訪問者分離操作與數據結構編譯器、數據分析
行為型中介者減少對象間依賴聊天室、協調復雜交互
行為型解釋器解析語言正則表達式、自定義DSL

關于設計模式的詳細內容將在后續專門介紹,如需了解,可以關注一下后續文章。

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

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

相關文章

網絡層和數據鏈路層

目錄 1.網絡層 2.數據鏈路層 1.網絡層 我們知道,我們的消息為了從A端發送到B端,達成遠距離傳輸,我們為此設計了很多協議層,分別是應用層,傳輸層,網絡層,數據鏈路層,網卡&#xff0c…

Redis 的字典:像智能文件柜一樣高效的哈希表實現

目錄 一、從傳統查找的痛點到哈希表的優勢? 二、哈希表的核心結構:文件柜的構成? 2.1、 dictht 結構體:文件柜本體? 2.2、dictEntry 結構體:帶鏈條的文件夾? 2.2.1、 哈希沖突的解決:抽屜里的鏈條? 2.3、字典的高層封裝…

FAST API部署和使用

第一部分:FastAPI 的使用(開發環境) 1. 安裝 首先,你需要安裝 FastAPI 和一個 ASGI 服務器,最常用的是 Uvicorn。 pip install "fastapi[standard]"這個命令會安裝 FastAPI 以及所有推薦的依賴,包…

【JavaWeb】之HTML(對HTML細節的一些總結)

大家天天開心! 文章目錄 前言一、HTML的簡介二、HTML運行方式三、html 的標簽/元素-說明四、表單注意事項總結 前言 首先我們在把Java基礎學習完之后,我們就要進行網站方面的開發了,我們要了解網頁的組成,而網頁的組成有HTML,CSS,…

互聯網醫院品牌IP的用戶體驗和生態構建

一、患者體驗與信任構建互聯網醫院品牌IP的價值核心在于獲得患者的深度信任,而卓越的用戶體驗是實現這一目標的關鍵路徑。在醫療服務同質化嚴重的當下,患者體驗已成為醫療機構差異化競爭的重要維度。研究表明,良好的用戶體驗能夠提高用戶滿意…

【Node.js教程】Express框架入門:從搭建到動態渲染商品列表

前言 Visual Studio Code(簡稱VSCode)是微軟開發的一款免費開源跨平臺代碼編輯器,憑借其免費、開源、跨平臺的特性,以及豐富的插件生態和美觀的界面,成為前端開發者的首選工具。 本文將帶你從零開始學習Express框架,包括搭建項目、配置路由、使用中間件以及實現動態渲染…

眾擎機器人開源代碼解讀

一,綜述 EngineAI ROS 包: 高層開發模式:用戶可通過發布身體速度指令,直接調用 EngineAI 機器人的行走控制器。底層開發模式:用戶可通過發布關節指令,自主開發專屬的控制器。 ROS2 package:全…

Windows系統安裝Git詳細教程

文章目錄步驟 1:下載 Git 安裝包步驟 2:運行安裝程序步驟 3:選擇安裝路徑步驟 4:選擇組件步驟 5:選擇默認編輯器步驟 6:選擇路徑環境變量步驟 7:選擇 HTTPS 協議的傳輸方式步驟 8:配…

leetcode 3446. 按對角線進行矩陣排序 中等

給你一個大小為 n x n 的整數方陣 grid。返回一個經過如下調整的矩陣:左下角三角形(包括中間對角線)的對角線按 非遞增順序 排序。右上角三角形 的對角線按 非遞減順序 排序。示例 1:輸入: grid [[1,7,3],[9,8,2],[4,…

攜程旅行 web 驗證碼 分析

聲明 本文章中所有內容僅供學習交流使用,不用于其他任何目的,抓包內容、敏感網址、數據接口等均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關! 逆向分析 部分python代碼 result cp…

JavaEE 進階第一期:開啟前端入門之旅(上)

專欄:JavaEE 進階躍遷營 個人主頁:手握風云 一、HTML基礎 1.1. 什么是HTML HTML(Hyper Text Markup Language),超文本標記語言。 超文本:比文本要強大,通過鏈接和交互式方式來組織和呈現信息的文本形式。不僅僅有文本…

4.5 PBR

1.PBR簡介 2.高光工作流 3.金屬工作流1.PBR簡介 PBR(Physically Based Rendering, 基于物理的渲染)的工作流分為金屬工作流和高光工作流2.高光工作流 高光工作流是一種傳統的工作流, 現在用的相對較少, 但是在某些特定情況下能提供更精細的控制a.核心思想它不區分金屬和非金屬,…

09.《路由基礎知識解析和實踐》

09.路由基礎 文章目錄09.路由基礎核心概念路由關鍵組成部分三層轉發原理介紹(通信流程)路由類型及配置直連路由(direct)實驗示例**靜態路由(Static)****實驗示例****動態路由****RIP(routing information protocol---路…

websocket建立連接過程

1. 客戶端發送一個GET的http請求,請求頭要包含connection: upgradehost:localhost:8000。表明地址upgrade: websocket。指明升級的協議sec-websocket-key 。 安全驗證密鑰sec-websocket-version。 協議版本sec-websocket-accept 。對傳過來的key進行加密…

Simulink庫文件-一種低通濾波模塊搭建方法

在汽車電控系統應用層開發中,經常會用到低通濾波模塊,其主要作用是去除輸入信號中的高頻干擾,防止由于輸入信號的干擾引起后續執行系統的非預期頻繁波動。本文介紹簡要介紹低通濾波的定義及作用,并介紹一種低通濾波模塊simulink搭…

【C++游記】AVL樹

楓の個人主頁 你不能改變過去,但你可以改變未來 算法/C/數據結構/C Hello,這里是小楓。C語言與數據結構和算法初階兩個板塊都更新完畢,我們繼續來學習C的內容呀。C是接近底層有比較經典的語言,因此學習起來注定枯燥無味&#xf…

音視頻學習(六十二):H264中的SEI

什么是SEI? 在 H.264 視頻編碼標準中,補充增強信息(Supplemental Enhancement Information,SEI) 是一種特殊的 NAL(網絡抽象層)單元。它不像序列參數集(SPS)或圖像參數集&#xff0…

docker run 后報錯/bin/bash: /bin/bash: cannot execute binary file總結

以下方法來源于AI&#xff0c;個人僅驗證了第三條便成功執行 1. 鏡像與宿主機架構不匹配 比如&#xff1a; 你是 x86_64 的機器&#xff0c;但鏡像是 ARM64 的&#xff08;或反之&#xff09;。在 PC 上拉了樹莓派用的鏡像。查看鏡像架構 docker inspect <image_name> | …

【Redisson 加鎖源碼解析】

Redisson 源碼解析 —— 分布式鎖實現過程 在分布式系統中&#xff0c;分布式鎖 是非常常見的需求&#xff0c;用來保證多個節點之間的互斥操作。Redisson 是 Redis 的一個 Java 客戶端&#xff0c;它提供了對分布式鎖的良好封裝。本文將從源碼角度剖析 Redisson 的分布式鎖實現…

uni-app支持單多選、搜索、查詢、限制能否點擊組件

<template><view class="multi-select-container" :class="{ single-select: !multiple, no-search: !searchable }"><!-- 當組件被禁用時,直接顯示選中的內容 --><view class="disabled-display" v-if="disabled &a…