一、設計模式三大分類總覽
- 創建型模式(5種)
核心目標:對象創建的優化與解耦
單例模式(Singleton)
工廠模式(Factory)
抽象工廠模式(Abstract Factory)
建造者模式(Builder)
原型模式(Prototype)
- 結構型模式(7種)
核心目標:類與對象組合的靈活架構
適配器模式(Adapter)
裝飾器模式(Decorator)
代理模式(Proxy)
外觀模式(Facade)
橋接模式(Bridge)
組合模式(Composite)
享元模式(Flyweight)
- 行為型模式(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() { /*...*/ }
}
技術深挖:
-
volatile關鍵字:防止JVM指令重排序導致對象未初始化完成就被使用(JVM規范允許的優化)
-
類加載機制:枚舉實現利用類加載的線程安全性保證單例
-
序列化攻擊防御:枚舉天然防反射和序列化破壞,普通實現需重寫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)——并發安全的終極形態
構建不可變類的五大鐵律:
- 所有字段final修飾
- 類聲明為final
- 不暴露可變引用
- 不提供setter方法
- 構造器完全初始化
深度防御示例:
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 |