Java設計模式:系統性解析與核心模式


一、設計模式三大分類總覽

  1. 創建型模式(5種)
    核心目標:對象創建的優化與解耦

單例模式(Singleton)

工廠模式(Factory)

抽象工廠模式(Abstract Factory)

建造者模式(Builder)

原型模式(Prototype)

  1. 結構型模式(7種)
    核心目標:類與對象組合的靈活架構

適配器模式(Adapter)

裝飾器模式(Decorator)

代理模式(Proxy)

外觀模式(Facade)

橋接模式(Bridge)

組合模式(Composite)

享元模式(Flyweight)

  1. 行為型模式(11種)
    核心目標:對象間的交互與職責分配

觀察者模式(Observer)

策略模式(Strategy)

命令模式(Command)

責任鏈模式(Chain of Responsibility)

狀態模式(State)

模板方法模式(Template Method)

迭代器模式(Iterator)

中介者模式(Mediator)

備忘錄模式(Memento)

訪問者模式(Visitor)

解釋器模式(Interpreter)

二、創建型模式深度解析

1. 單例模式(Singleton)——對象創建的終極控制

核心特征:全局唯一實例 + 延遲初始化 + 線程安全

演進式實現對比
// 1. 餓漢式(線程安全但立即加載)
public class EagerSingleton {private static final EagerSingleton INSTANCE = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() { return INSTANCE; }
}// 2. 雙重校驗鎖(DCL)實現
public class DCLSingleton {private static volatile DCLSingleton instance; // volatile禁止指令重排序private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance == null) {                    // 第一次檢查synchronized (DCLSingleton.class) {    // 鎖粒度控制if (instance == null) {            // 第二次檢查instance = new DCLSingleton();  // 安全發布}}}return instance;}
}// 3. 枚舉實現(《Effective Java》推薦方式)
public enum EnumSingleton {INSTANCE;public void businessMethod() { /*...*/ }
}

技術深挖

  1. volatile關鍵字:防止JVM指令重排序導致對象未初始化完成就被使用(JVM規范允許的優化)

  2. 類加載機制:枚舉實現利用類加載的線程安全性保證單例

  3. 序列化攻擊防御:枚舉天然防反射和序列化破壞,普通實現需重寫readResolve()

典型應用場景

// Java原生API中的單例
Runtime runtime = Runtime.getRuntime();      // JVM運行時環境單例
Desktop desktop = Desktop.getDesktop();     // 桌面操作單例

2. 工廠模式(Factory)——對象創建的工業化革命

模式演進三階段
簡單工廠 → 工廠方法 → 抽象工廠

工廠方法模式(Factory Method)
// 產品接口
public interface DatabaseConnection {void connect();
}// 具體產品
public class MySQLConnection implements DatabaseConnection {@Override public void connect() { System.out.println("MySQL connected"); }
}// 抽象工廠
public abstract class ConnectionFactory {public abstract DatabaseConnection createConnection();// 模板方法public void initializeConnection() {DatabaseConnection conn = createConnection();conn.connect();// 公共初始化邏輯...}
}// 具體工廠
public class MySQLFactory extends ConnectionFactory {@Overridepublic DatabaseConnection createConnection() {return new MySQLConnection();}
}

Spring框架中的高級應用

<!-- Bean配置工廠方法 -->
<bean id="mysqlFactory" class="com.example.MySQLFactory"/>
<bean id="connection" factory-bean="mysqlFactory" factory-method="createConnection"/>

三、結構型模式實戰精講

1. 適配器模式(Adapter)——接口轉換的藝術

兩種實現方式對比

類型實現方式適用場景Java示例
類適配器繼承被適配類需要復用現有類代碼較少使用
對象適配器組合被適配對象更靈活的解耦方式InputStreamReader

JDK中的經典實現

// 將字節流轉換為字符流
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);

現代Java中的函數式適配

// 使用Lambda適配舊接口
Runnable legacyTask = () -> System.out.println("Old task");
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(legacyTask::run);

2. 裝飾器模式(Decorator)——動態增強的利器

模式結構

          Component↑   ↑ConcreteComponent ← Decorator↑ConcreteDecoratorA

Java IO流的裝飾器體系

// 多層裝飾示例
InputStream in = new FileInputStream("data.txt");
in = new BufferedInputStream(in);          // 添加緩沖功能
in = new GZIPInputStream(in);              // 添加壓縮解壓功能

自定義裝飾器實現

public class CryptoInputStream extends FilterInputStream {private Cipher cipher;public CryptoInputStream(InputStream in, SecretKey key) throws GeneralSecurityException {super(in);cipher = Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE, key);}@Overridepublic int read(byte[] b, int off, int len) throws IOException {int bytesRead = super.read(b, off, len);if (bytesRead > 0) {try {cipher.doFinal(b, off, bytesRead);  // 解密處理} catch (IllegalBlockSizeException | BadPaddingException e) {throw new IOException("Decryption failed", e);}}return bytesRead;}
}

四、行為型模式核心剖析

1. 觀察者模式(Observer)——事件驅動的基石

Java內置實現演進

// 傳統實現(已過時但仍有參考價值)
public class Observable {private boolean changed = false;private Vector<Observer> observers;public synchronized void addObserver(Observer o) { /*...*/ }public void notifyObservers(Object arg) {// 同步通知邏輯...}
}// 現代實現(推薦)
public class PropertyChangeSupport {public void addPropertyChangeListener(PropertyChangeListener listener) { /*...*/ }public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {// 事件派發...}
}

響應式編程擴展(RxJava示例):

Observable<String> observable = Observable.create(emitter -> {emitter.onNext("Event 1");emitter.onNext("Event 2");emitter.onComplete();
});observable.subscribe(event -> System.out.println("Received: " + event),error -> System.err.println("Error: " + error),() -> System.out.println("Completed")
);

2. 策略模式(Strategy)——算法族的自由切換

Lambda表達式帶來的革新

// 傳統實現
public interface ValidationStrategy {boolean execute(String s);
}public class IsNumeric implements ValidationStrategy {@Overridepublic boolean execute(String s) {return s.matches("\\d+");}
}// Lambda實現
ValidationStrategy numericStrategy = s -> s.matches("\\d+");
ValidationStrategy lowerCaseStrategy = s -> s.matches("[a-z]+");// 上下文使用
public class Validator {private ValidationStrategy strategy;public Validator(ValidationStrategy v) { this.strategy = v; }public boolean validate(String s) { return strategy.execute(s); }
}

Java集合框架的典型應用

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Collections.sort(names, (a, b) -> b.compareTo(a));  // 策略注入

五、Java特有模式深度探討

1. 空對象模式(Null Object)——防御式編程的優雅解決方案

完整實現示例

public interface Logger {void log(String message);
}public class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println(message);}
}public class NullLogger implements Logger {@Overridepublic void log(String message) {// 靜默處理}
}// 客戶端使用
public class PaymentService {private Logger logger = new NullLogger();  // 默認安全public void setLogger(Logger logger) {this.logger = Objects.requireNonNullElse(logger, new NullLogger());}public void processPayment() {logger.log("Payment started");// 業務邏輯...}
}

2. 不可變對象模式(Immutable Object)——并發安全的終極形態

構建不可變類的五大鐵律

  1. 所有字段final修飾
  2. 類聲明為final
  3. 不暴露可變引用
  4. 不提供setter方法
  5. 構造器完全初始化

深度防御示例

public final class ImmutablePerson {private final String name;private final Date birthDate;  // Date本身可變public ImmutablePerson(String name, Date birthDate) {this.name = name;// 防御性拷貝this.birthDate = new Date(birthDate.getTime());}public Date getBirthDate() {// 返回拷貝對象return new Date(birthDate.getTime());}
}

六、模式應用黃金法則

1. 模式選擇決策樹

是否需要控制對象創建? → 創建型模式├─ 需要全局唯一實例 → 單例├─ 需要復雜構造過程 → 建造者└─ 需要靈活的產品族 → 抽象工廠是否需要重組對象結構? → 結構型模式├─ 接口不兼容 → 適配器├─ 需要透明擴展 → 裝飾器└─ 控制對象訪問 → 代理是否需要協調對象行為? → 行為型模式├─ 事件通知機制 → 觀察者├─ 算法動態切換 → 策略└─ 流程標準化 → 模板方法

2. 模式反模式警示

  • 單例濫用:導致隱藏的依賴關系和測試困難
  • 過度裝飾:產生過多小對象影響性能
  • 觀察者泄漏:未及時取消注冊導致內存泄漏
  • 策略膨脹:大量策略類增加維護成本

七、現代Java中的模式演進

1. Lambda表達式對傳統模式的沖擊

策略模式簡化

// 傳統方式
Arrays.sort(words, new Comparator<String>() {public int compare(String a, String b) {return Integer.compare(a.length(), b.length());}
});// Lambda簡化
Arrays.sort(words, (a, b) -> Integer.compare(a.length(), b.length()));

2. 模塊化帶來的模式變化

服務加載器替代工廠模式

// META-INF/services/com.example.DatabaseConnection
ServiceLoader<DatabaseConnection> loader = ServiceLoader.load(DatabaseConnection.class);
DatabaseConnection conn = loader.findFirst().orElseThrow();

八、設計模式在Java生態中的典型應用

框架/庫核心模式具體實現
Spring工廠模式、代理模式、模板方法BeanFactory、AOP代理、JdbcTemplate
Hibernate代理模式、工廠模式延遲加載代理、SessionFactory
JavaFX觀察者模式、命令模式Property綁定、EventHandler
Netty責任鏈模式、Reactor模式ChannelPipeline、EventLoop

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

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

相關文章

Elasticsearch 向量數據庫,原生支持 Google Cloud Vertex AI 平臺

作者&#xff1a;來自 Elastic Valerio Arvizzigno Elasticsearch 將作為第一個第三方原生語義對齊引擎&#xff0c;支持 Google Cloud 的 Vertex AI 平臺和 Google 的 Gemini 模型。這使得聯合用戶能夠基于企業數據構建完全可定制的生成式 AI 體驗&#xff0c;并借助 Elastics…

408 計算機網絡 知識點記憶(7)

前言 本文基于王道考研課程與湖科大計算機網絡課程教學內容&#xff0c;系統梳理核心知識記憶點和框架&#xff0c;既為個人復習沉淀思考&#xff0c;亦希望能與同行者互助共進。&#xff08;PS&#xff1a;后續將持續迭代優化細節&#xff09; 往期內容 408 計算機網絡 知識…

10-MySQL-性能優化思路

1、優化思路 當我們發現了一個慢SQL的問題的時候,需要做性能優化,一般我們是為了提高SQL查詢更快,一個查詢的流程由下圖的各環節組成,每個環節都會消耗時間,要減少消耗時候需要從各個環節都分析一遍。 2 連接配置優化 第一個環節是客戶端連接到服務端,這塊可能會出現服務…

Docker:安裝與部署 Nacos 的技術指南

1、簡述 Nacos(Dynamic Naming and Configuration Service)是阿里巴巴開源的一個動態服務發現、配置管理和服務治理的綜合解決方案,適用于微服務架構。 Nacos 主要功能: 服務發現與注冊:支持 Dubbo、Spring Cloud 等主流微服務框架的服務發現與注冊。動態配置管理:支持…

【非機動車檢測】用YOLOv8實現非機動車及駕駛人佩戴安全帽檢測

非機動車及駕駛人佩戴安全帽檢測任務的意義主要包括以下幾點&#xff1a; 保障行車安全&#xff1a;非機動車包括自行車、電動車等&#xff0c;佩戴安全帽能夠有效保護騎車人頭部&#xff0c;減少因交通事故造成的頭部傷害風險&#xff0c;提高行車安全系數。 符合交通法規&am…

壹起航:15年深耕互聯網營銷,助力中國工廠出海獲客

在全球化浪潮下&#xff0c;越來越多的中國工廠渴望拓展海外市場&#xff0c;但面臨品牌建立、穩定詢盤獲取及營銷成本降低等多重挑戰。壹起航憑借15年的豐富經驗&#xff0c;整合外貿建站、SEO優化及海外短視頻營銷&#xff0c;為中國工廠提供一站式出海解決方案。 一、外貿獨…

Emacs 折騰日記(二十)——修改emacs的一些默認行為

上一篇我們完成了emacs輸入法的配置以及將emacs配置成了使用vim的操作方式。但是emacs目前有些默認行為我不太喜歡&#xff0c;這節我們一起來修改它 備份設置 我們打開emacs的配置文件所在路徑&#xff0c;發現有大量的~結尾的文件&#xff0c;這是emacs的備份文件。這里&am…

聊透多線程編程-線程基礎-4.C# Thread 子線程執行完成后通知主線程執行特定動作

在多線程編程中&#xff0c;線程之間的同步和通信是一個常見的需求。例如&#xff0c;我們可能需要一個子線程完成某些任務后通知主線程&#xff0c;并由主線程執行特定的動作。本文將基于一個示例程序&#xff0c;詳細講解如何使用 AutoResetEvent 來實現這種場景。 示例代碼…

【網絡安全 | 項目開發】Web 安全響應頭掃描器(提升網站安全性)

原創項目,未經許可,不得轉載。 文章目錄 項目簡介工作流程示例輸出技術棧項目代碼使用說明項目簡介 安全響應頭是防止常見 Web 攻擊(如點擊劫持、跨站腳本攻擊等)的有效防線,因此合理的配置這些頭部信息對任何網站的安全至關重要。 Web 安全響應頭掃描器(Security Head…

使用libcurl編寫爬蟲程序指南

用戶想知道用Curl庫編寫的爬蟲程序是什么樣的。首先&#xff0c;我需要明確Curl本身是一個命令行工具和庫&#xff0c;用于傳輸數據&#xff0c;支持多種協議。而用戶提到的“Curl庫”可能指的是libcurl&#xff0c;這是一個客戶端URL傳輸庫&#xff0c;可以用在C、C等編程語言…

使用pip3安裝PyTorch與PyG,實現NVIDIA CUDA GPU加速

使用python3的pip3命令安裝python依賴庫。 # python3 -V Python 3.12.3 # # pip3 -V pip 25.0.1 from /root/.pyenv/versions/3.12.3/lib/python3.12/site-packages/pip (python 3.12)Usage: pip3 install [options] <package> ...pip3 install [options] -r <re…

五種常用的web加密算法

文章目錄 五種常用Web加密算法實戰及原理詳解1. AES (高級加密標準)原理詳解應用場景實戰代碼&#xff08;Node.js&#xff09; 2. RSA (非對稱加密)原理詳解應用場景實戰代碼&#xff08;Node.js&#xff09; 3. SHA-256 (安全哈希算法)原理詳解應用場景實戰代碼&#xff08;瀏…

深入解析 C++ 設計模式:原理、實現與應用

一、引言 在 C 編程的廣袤領域中&#xff0c;設計模式猶如閃耀的燈塔&#xff0c;為開發者指引著構建高效、可維護軟件系統的方向。設計模式并非神秘莫測的代碼魔法&#xff0c;實際上&#xff0c;我們在日常編程中或許早已與之打過交道。簡單來說&#xff0c;設計模式常常借助…

Python刷題筆記

Python刷題筆記 1、輸出格式化 第一種格式化的輸出&#xff1a; name "jack" age 17 salary 20031.8752 print("你的名字是&#xff1a;%s,今年 %d 歲,工資 %7.2f" % (name,age,salary) ) --------------------------------------- 你的名字是&#…

【Kubernetes】Kubernetes 如何進行日志管理?Fluentd / Loki / ELK 適用于什么場景?

由于 Kubernetes 運行在容器化的環境中&#xff0c;應用程序和系統日志通常分布在多個容器和節點上&#xff0c;傳統的日志管理方法&#xff08;例如直接訪問每個節點的日志文件&#xff09;在 Kubernetes 中不適用。 因此&#xff0c;Kubernetes 引入了集中式日志管理方案&am…

Ansible(8)——循環與條件任務

目錄 一、循環迭代任務&#xff1a; 1、簡單循環&#xff1a; 2、循環字典列表&#xff1a; 3、Ansible 2.5 之前的循環關鍵字&#xff1a; 4、在循環中使用 register 變量&#xff1a; 二、條件任務&#xff1a; 1、使用條件句的常見場景&#xff1a; 2、條件任務語法…

adb|scrcpy的安裝和配置方法|手機投屏電腦|手機聲音投電腦|adb連接模擬器或手機

adb|scrcpy的安裝和配置方法手機投屏電腦|手機聲音投電腦|adb連接模擬器或手機或電視 引言 在數字設備交織的現代生活中&#xff0c;adb&#xff08;Android Debug Bridge&#xff09;與 scrcpy 宛如隱匿的強大工具&#xff0c;極大地拓展了我們操控手機、模擬器乃至智能電視等…

vue3項目集成electron

一、環境準備 1. 確保已安裝 Node.js (建議版本 16.x 或更高) 2. 創建或進入現有 Vue 項目目錄 cd your-vue-project 二、添加 Electron 支持 在項目根目錄執行: vue add electron-builder 執行后會在 `src` 目錄下生成 `background.js` 主進程文件。 三、主進程配置 (ba…

循環神經網絡 - 參數學習之隨時間反向傳播算法

本文中&#xff0c;我們以同步的序列到序列模式為例來介紹循環神經網絡的參數學習。 循環神經網絡中存在一個遞歸調用的函數 &#x1d453;(?)&#xff0c;因此其計算參數梯度的方式和前饋神經網絡不太相同。在循環神經網絡中主要有兩種計算梯度的方式&#xff1a;隨時間反向…

體驗OceanBase的 并行導入功能

在數據庫的日常使用中&#xff0c;會經常遇到以下場景&#xff1a; ?數據復制?&#xff1a;將一個或多個表中的數據復制到目標表中&#xff0c;可能是復制全部數據&#xff0c;也可能僅復制部分數據。數據合并&#xff1a;將數據從一個表轉移到另一個表&#xff0c;或者將多…