【設計模式】3W 學習法全面解析 7 大結構型模式:Java 實戰 + 開源框架應用

3W 學習法總結結構型模式(附 Java 代碼實戰及開源框架應用)

結構型模式 主要關注 類與對象的組合,確保不同組件之間能夠高效協作,提高系統的靈活性和可維護性。本文采用 3W 學習法(What、Why、How),深入分析 七大結構型模式(適配器、橋接、裝飾器、組合、外觀、享元、代理),并結合 Java 代碼實戰開源框架中的應用,幫助你高效掌握這些模式的實戰技巧。


1. 適配器模式(Adapter)

? What:適配器模式是什么?

適配器模式 通過 轉換接口 使原本不兼容的類能夠一起工作。

🤔 Why:為什么要使用適配器模式?

  • 解決接口不兼容問題,讓新舊代碼無縫銜接。
  • 復用已有代碼,避免修改原始代碼。

🚀 How:如何實現適配器模式?(Java 代碼實戰)

// 目標接口
interface Target {void request();
}// 需要適配的類
class Adaptee {void specificRequest() {System.out.println("Adaptee 特定請求");}
}// 適配器
class Adapter implements Target {private Adaptee adaptee = new Adaptee();public void request() {adaptee.specificRequest();}
}// 客戶端調用
public class AdapterDemo {public static void main(String[] args) {Target target = new Adapter();target.request(); // 輸出: Adaptee 特定請求}
}

📌 在開源框架中的應用:

  • Spring HandlerAdapter:適配不同類型的 Controller(如 RequestMappingHandlerAdapter)。
  • java.io.InputStreamReader:將 InputStream 適配為 Reader

2. 橋接模式(Bridge)

? What:橋接模式是什么?

橋接模式 通過 分離抽象部分和實現部分,讓它們可以獨立變化。

🤔 Why:為什么要使用橋接模式?

  • 降低耦合:抽象和實現獨立演化,不受對方影響。
  • 增強擴展性:適用于 多個維度變化 的場景。

🚀 How:如何實現橋接模式?(Java 代碼實戰)

// 實現接口
interface Implementor {void operationImpl();
}// 具體實現A
class ConcreteImplementorA implements Implementor {public void operationImpl() {System.out.println("具體實現A的操作");}
}// 抽象類
abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}abstract void operation();
}// 具體抽象類
class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}public void operation() {implementor.operationImpl();}
}// 客戶端調用
public class BridgeDemo {public static void main(String[] args) {Implementor impl = new ConcreteImplementorA();Abstraction abstraction = new RefinedAbstraction(impl);abstraction.operation(); // 輸出: 具體實現A的操作}
}

📌 在開源框架中的應用:

  • JDBC 驅動java.sql.DriverManager 通過橋接不同數據庫的驅動。
  • Slf4j + Logback/Log4j:日志框架使用橋接模式適配不同日志實現。

3. 裝飾器模式(Decorator)

? What:裝飾器模式是什么?

裝飾器模式 通過 動態添加新功能,而不修改原有對象。

🤔 Why:為什么要使用裝飾器模式?

  • 符合開閉原則:可擴展對象功能,避免修改原始代碼。
  • 支持功能疊加:適用于 多個額外行為 組合的場景。

🚀 How:如何實現裝飾器模式?(Java 代碼實戰)

// 抽象組件
interface Component {void operation();
}// 具體組件
class ConcreteComponent implements Component {public void operation() {System.out.println("基本功能");}
}// 裝飾器
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// 具體裝飾器A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void operation() {super.operation();System.out.println("附加功能A");}
}// 客戶端調用
public class DecoratorDemo {public static void main(String[] args) {Component component = new ConcreteDecoratorA(new ConcreteComponent());component.operation();// 輸出:// 基本功能// 附加功能A}
}

📌 在開源框架中的應用:

  • Spring BeanPostProcessor:可動態增強 Bean 的功能。
  • BufferedInputStream:裝飾 InputStream,提供緩沖能力。

4. 組合模式(Composite)

? What:組合模式是什么?

組合模式 允許 樹形結構的對象 統一處理。

🤔 Why:為什么要使用組合模式?

  • 統一對象處理方式:無論是單個對象還是組合對象,均可一致調用。
  • 適用于層級結構:如 文件系統、組織架構 等。

🚀 How:如何實現組合模式?(Java 代碼實戰)

// 抽象組件
interface Component {void operation();
}// 葉子節點
class Leaf implements Component {public void operation() {System.out.println("執行葉子節點操作");}
}// 組合節點
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void operation() {for (Component child : children) {child.operation();}}
}// 客戶端調用
public class CompositeDemo {public static void main(String[] args) {Composite root = new Composite();root.add(new Leaf());root.add(new Leaf());Composite branch = new Composite();branch.add(new Leaf());root.add(branch);root.operation();}
}

📌 在開源框架中的應用:

  • Spring Security:權限規則采用組合模式組織權限節點。
  • GUI 組件:Swing 的 JComponent 使用組合模式。

確實,結構型模式共有 7 種,前面只介紹了 4 種,缺少了 外觀模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)。下面繼續補充它們的 3W 學習法解析、Java 實戰代碼及在開源框架中的應用


5. 外觀模式(Facade)

? What:外觀模式是什么?

外觀模式(Facade) 通過 提供一個統一的接口,簡化子系統的復雜操作,降低系統耦合性。

🤔 Why:為什么要使用外觀模式?

  • 降低復雜性,隱藏子系統細節,使調用者只需與一個簡單接口交互。
  • 解耦代碼,避免高層代碼直接依賴多個復雜子系統。

🚀 How:如何實現外觀模式?(Java 代碼實戰)

// 子系統A
class SubsystemA {void operationA() {System.out.println("子系統 A 操作");}
}// 子系統B
class SubsystemB {void operationB() {System.out.println("子系統 B 操作");}
}// 外觀類(Facade)
class Facade {private SubsystemA subsystemA = new SubsystemA();private SubsystemB subsystemB = new SubsystemB();void operation() {subsystemA.operationA();subsystemB.operationB();}
}// 客戶端調用
public class FacadeDemo {public static void main(String[] args) {Facade facade = new Facade();facade.operation();// 輸出:// 子系統 A 操作// 子系統 B 操作}
}

📌 在開源框架中的應用:

  • Spring JdbcTemplate:封裝了數據庫操作,簡化 JDBC 使用。
  • HttpClient:簡化底層 HTTP 請求的復雜性。

6. 享元模式(Flyweight)

? What:享元模式是什么?

享元模式(Flyweight) 通過 共享對象 來減少內存占用,提高性能。

🤔 Why:為什么要使用享元模式?

  • 減少內存開銷,適用于 大量相似對象 場景。
  • 提升系統性能,避免重復創建對象。

🚀 How:如何實現享元模式?(Java 代碼實戰)

import java.util.HashMap;
import java.util.Map;// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具體享元
class ConcreteFlyweight implements Flyweight {private final String intrinsicState;ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("享元對象:" + intrinsicState + ",外部狀態:" + extrinsicState);}
}// 享元工廠
class FlyweightFactory {private static final Map<String, Flyweight> pool = new HashMap<>();static Flyweight getFlyweight(String key) {if (!pool.containsKey(key)) {pool.put(key, new ConcreteFlyweight(key));}return pool.get(key);}
}// 客戶端調用
public class FlyweightDemo {public static void main(String[] args) {Flyweight fw1 = FlyweightFactory.getFlyweight("A");Flyweight fw2 = FlyweightFactory.getFlyweight("A");Flyweight fw3 = FlyweightFactory.getFlyweight("B");fw1.operation("X");fw2.operation("Y");fw3.operation("Z");System.out.println(fw1 == fw2); // 輸出: true(共享同一個對象)}
}

📌 在開源框架中的應用:

  • Integer.valueOf(int):JDK 享元模式,緩存 -128 ~ 127 的 Integer 對象。
  • 線程池(Thread Pool):復用線程對象,減少資源消耗。

7. 代理模式(Proxy)

? What:代理模式是什么?

代理模式(Proxy) 通過 控制訪問目標對象,增加額外行為(如權限控制、懶加載、緩存等)。

🤔 Why:為什么要使用代理模式?

  • 增強功能(如日志、事務、權限)。
  • 控制對象訪問(如遠程代理、虛擬代理)。

🚀 How:如何實現代理模式?(Java 代碼實戰)

靜態代理
// 接口
interface Service {void operation();
}// 真實對象
class RealService implements Service {public void operation() {System.out.println("真實業務邏輯");}
}// 代理類
class ProxyService implements Service {private RealService realService = new RealService();public void operation() {System.out.println("前置增強邏輯");realService.operation();System.out.println("后置增強邏輯");}
}// 客戶端調用
public class StaticProxyDemo {public static void main(String[] args) {Service service = new ProxyService();service.operation();// 輸出:// 前置增強邏輯// 真實業務邏輯// 后置增強邏輯}
}
動態代理(JDK 動態代理)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 動態代理處理器
class DynamicProxyHandler implements InvocationHandler {private Object target;DynamicProxyHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置增強邏輯");Object result = method.invoke(target, args);System.out.println("后置增強邏輯");return result;}
}// 客戶端調用
public class DynamicProxyDemo {public static void main(String[] args) {Service realService = new RealService();Service proxy = (Service) Proxy.newProxyInstance(realService.getClass().getClassLoader(),realService.getClass().getInterfaces(),new DynamicProxyHandler(realService));proxy.operation();// 輸出:// 前置增強邏輯// 真實業務邏輯// 后置增強邏輯}
}

📌 在開源框架中的應用:

  • Spring AOP:代理模式增強 Bean 功能,如事務、日志、權限控制。
  • MyBatis Mapper:動態代理生成 SQL 查詢接口的實現類。

總結

設計模式主要作用適用場景
適配器模式讓不兼容的接口協同工作HandlerAdapterInputStreamReader
橋接模式分離抽象和實現,解耦JDBC 驅動、日志框架
裝飾器模式動態增強對象功能BufferedInputStreamBeanPostProcessor
組合模式統一樹形結構處理Spring Security 權限管理、GUI 組件
外觀模式簡化系統調用JdbcTemplateHttpClient
享元模式共享對象減少內存消耗Integer.valueOf(int)、線程池
代理模式控制訪問目標對象,增強功能AOP、MyBatis 動態代理

掌握這 7 大結構型模式,讓你的代碼 更清晰、可擴展、性能更優!🚀

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

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

相關文章

在大數據開發中ETL是指什么?

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在數字經濟時代&#xff0c;數據已成為企業最核心的資產。然而&#xff0c;分散在業務系統、日志文件…

前端面試項目拷打

Axios相關 1.在Axios二次封裝時&#xff0c;具體封裝了哪些內容&#xff0c;如何處理請求攔截和響應攔截&#xff1f; axios二次封裝的目的&#xff1a;為了統一處理請求和響應攔截器、錯誤處理、請求超時、請求頭配置等&#xff0c;提高代碼可維護性和復用性。 首先創建axios…

「JavaScript深入」Server-Sent Events (SSE):輕量級實時通信技術

Server-Sent Events&#xff08;SSE&#xff09; SSE 的特點1. 單向通信2. 簡單易用&#xff0c;瀏覽器原生支持3. 持久連接4. 純文本傳輸5. 自動重連機制6. 輕量級協議 SSE 的實現服務器端實現&#xff08;Node.js 示例&#xff09;1. HTTP 響應頭設置2. 數據推送模式3. 服務器…

藍橋杯2023年第十四屆省賽真題-階乘的和

藍橋杯2023年第十四屆省賽真題-階乘的和 時間限制: 2s 內存限制: 320MB 提交: 3519 解決: 697 題目描述 給定 n 個數 Ai&#xff0c;問能滿足 m! 為∑ni1(Ai!) 的因數的最大的 m 是多少。其中 m! 表示 m 的階乘&#xff0c;即 1 2 3 m。 輸入格式 輸入的第一行包含一個整…

影刀RPA拓展-Python變量類型轉換

1. Python變量類型轉換概述 1.1 類型轉換的必要性 Python作為一種動態類型語言&#xff0c;在編程過程中經常需要進行變量類型轉換。這主要是因為不同數據類型在存儲結構、運算規則和使用場景上存在差異&#xff0c;而在實際開發中&#xff0c;我們常常需要對不同類型的數據進…

Python pyqt+flask做一個簡單實用的自動排班系統

這是一個基于Flask和PyQt的排班系統&#xff0c;可以將Web界面嵌入到桌面應用程序中。 系統界面&#xff1a; 功能特點&#xff1a; - 讀取員工信息和現有排班表 - 自動生成排班表 - 美觀的Web界面 - 獨立的桌面應用程序 整體架構&#xff1a; 系統采用前后端分離的架構…

Pycharm接入DeepSeek,提升自動化腳本的寫作效率

一.效果展示&#xff1a; 二.實施步驟&#xff1a; 1.DeepSeek官網創建API key&#xff1a; 創建成功后&#xff0c;會生成一個API key&#xff1a; 2. PyCharm工具&#xff0c;打開文件->設置->插件&#xff0c;搜索“Continue”&#xff0c;點擊安裝 3.安裝完成后&…

Java:Arrays類:操作數組的工具類

文章目錄 Arrays類常見方法SetAll(); 代碼排序如果數組中存儲的是自定義對象 Arrays類 常見方法 SetAll(); 注意&#xff1a; 不能用新的數組接是因為修改的是原數組&#xff0c;所以完了要輸出原數組發現會產生變化參數是數組下標變成灰色是因為還能簡化&#xff08;Lambda…

2025-gazebo配置on vmware,wsl

ros2安裝 # 安裝ros2, 推薦魚香ros一鍵式安裝 wget http://fishros.com/install -O fishros && . fishros安裝版本&#xff1a;ubuntu24.04 ros2 jazzy gazebo Getting Started with Gazebo? — Gazebo ionic documentation ros與gz的版本對應關系&#xff1a; ?…

格力地產更名“珠免集團“ 全面轉型免稅賽道

大灣區經濟網品牌觀察訊&#xff0c;3月18日&#xff0c;格力地產股份有限公司公告宣布&#xff0c;擬將公司名稱變更為"珠海珠免集團股份有限公司"&#xff0c;證券簡稱同步變更為"珠免集團"。此次更名并非簡單的品牌煥新&#xff0c;而是標志著這家曾以房…

網絡編程--服務器雙客戶端聊天

寫一個服務器和客戶端 運行服務器和2個客戶端&#xff0c;實現聊天功能 客戶端1和客戶端2進行聊天&#xff0c;客戶端1將聊天數據發送給服務器&#xff0c;服務器將聊天數據轉發給客戶端2 要求&#xff1a; 服務器使用 select 模型實現 &#xff0c;客戶端1使用 poll 模型實現…

k8s主要控制器簡述(一)ReplicaSet與Deployment

目錄 一、ReplicaSet 關鍵特性 示例 解釋 支持的 Operator 二、Deployment 1. 聲明式更新 示例 2. 滾動更新 示例 3. 回滾 示例 4. ReplicaSet 管理 示例 5. 自動恢復 示例 6. 擴展和縮容 示例 示例 一、ReplicaSet ReplicaSet 是 Kubernetes 中的一個核心控…

python中redis操作整理

下載redis命令 pip install redis 連接redis import redis # host是redis主機&#xff0c;需要redis服務端和客戶端都起著 redis默認端口是6379 pool redis.ConnectionPool(hostlocalhost, port6379,decode_responsesTrue) r redis.Redis(connection_poolpool)操作字符串 …

自然語言處理入門4——RNN

一般來說&#xff0c;提到自然語言處理&#xff0c;我們都會涉及到循環神經網絡&#xff08;RNN&#xff09;&#xff0c;這是因為自然語言可以被看作是一個時間序列&#xff0c;這個時間序列中的元素是一個個的token。傳統的前饋神經網絡結構簡單&#xff0c;但是不能很好的處…

數據結構之鏈表(雙鏈表)

目錄 一、雙向帶頭循環鏈表 概念 二、哨兵位的頭節點 優點&#xff1a; 頭節點的初始化 三、帶頭雙向鏈表的實現 1.雙鏈表的銷毀 2.雙鏈表的打印 3.雙鏈表的尾插和頭插 尾插&#xff1a; 頭插&#xff1a; 4.雙鏈表的尾刪和頭刪 尾刪&#xff1a; 頭刪&#xff1a; …

ASP3605同步降壓調節器——滿足汽車電子嚴苛要求的電源芯片方案

ASP3605高效同步降壓調節器&#xff0c;通過AEC-Q100 Grade1認證&#xff0c;輸入電壓4V至15V&#xff0c;輸出電流5A&#xff0c;峰值效率94%。車規級型號ASP3605A3U支持-40C至125C工作溫度&#xff0c;適用于ADAS、車載信息娛樂系統等場景。 面向汽車電子的核心功能設計 1. …

vue3+Ts+elementPlus二次封裝Table分頁表格,表格內展示圖片、switch開關、支持

目錄 一.項目文件結構 二.實現代碼 1.子組件&#xff08;表格組件&#xff09; 2.父組件&#xff08;使用表格&#xff09; 一.項目文件結構 1.表格組件&#xff08;子組件&#xff09;位置 2.使用表格組件的頁面文件&#xff08;父組件&#xff09;位置 3.演示圖片位置 ele…

[特殊字符]1.2.1 新型基礎設施建設

&#x1f680; 新型基礎設施建設全解析 &#x1f31f; 核心概念與定義 維度詳細內容定義以新發展理念為引領&#xff0c;以技術創新為驅動&#xff0c;以信息網絡為基礎&#xff0c;提供數字轉型、智能升級、融合創新服務的基礎設施體系。提出背景2018年中央經濟工作會議首次提…

SQL Server數據庫慢SQL調優

SQL Server中慢SQL會顯著降低系統性能并引發級聯效應。首先&#xff0c;用戶直接體驗響應時間延長&#xff0c;核心業務操作&#xff08;如交易處理、報表生成&#xff09;效率下降&#xff0c;導致客戶滿意度降低甚至業務中斷。其次&#xff0c;資源利用率失衡&#xff0c;CPU…

【安全運營】安全運營關于告警降噪的一些梳理

目錄 前言一、智能技術層面1、機器學習和 AI 模型訓練2、攻擊成功判定 二、多源關聯分析1、多源設備關聯&#xff08;跨設備日志整合&#xff09;2、上下文信息增強 三、業務白名單和策略優化1、動態白名單機制2、閾值和規則調整 四、自動化和流程化1、告警歸并與去重2、同類型…