目录
- [🟠 33 设计模式精讲](#🟠 33 设计模式精讲)
-
- [1. 设计模式概述](#1. 设计模式概述)
-
- [1.1 什么是设计模式](#1.1 什么是设计模式)
- [1.2 三大分类](#1.2 三大分类)
- [1.3 设计原则 (SOLID)](#1.3 设计原则 (SOLID))
- [2. 单例模式](#2. 单例模式)
-
- [2.1 适用场景](#2.1 适用场景)
- [2.2 实现方式](#2.2 实现方式)
- [2.3 JDK中的单例](#2.3 JDK中的单例)
- [3. 工厂模式](#3. 工厂模式)
-
- [3.1 简单工厂](#3.1 简单工厂)
- [3.2 工厂方法](#3.2 工厂方法)
- [3.3 JDK中的工厂](#3.3 JDK中的工厂)
- [4. 策略模式](#4. 策略模式)
-
- [4.1 定义](#4.1 定义)
- [4.2 实现](#4.2 实现)
- [4.3 Lambda简化](#4.3 Lambda简化)
- [4.4 JDK中的策略](#4.4 JDK中的策略)
- [5. 观察者模式](#5. 观察者模式)
-
- [5.1 定义](#5.1 定义)
- [5.2 实现](#5.2 实现)
- [5.3 JDK中的观察者](#5.3 JDK中的观察者)
- [6. 模板方法模式](#6. 模板方法模式)
-
- [6.1 定义](#6.1 定义)
- [6.2 实现](#6.2 实现)
- [6.3 JDK中的模板方法](#6.3 JDK中的模板方法)
- [7. 建造者模式](#7. 建造者模式)
-
- [7.1 定义](#7.1 定义)
- [7.2 实现](#7.2 实现)
- [7.3 JDK中的建造者](#7.3 JDK中的建造者)
- [8. 适配器模式](#8. 适配器模式)
-
- [8.1 定义](#8.1 定义)
- [8.2 实现](#8.2 实现)
- [8.3 JDK中的适配器](#8.3 JDK中的适配器)
- [9. 装饰器模式](#9. 装饰器模式)
-
- [9.1 定义](#9.1 定义)
- [9.2 实现](#9.2 实现)
- [9.3 JDK中的装饰器](#9.3 JDK中的装饰器)
- [10. 总结](#10. 总结)
- [📚 参考资料](#📚 参考资料)
🟠 33 设计模式精讲
📅 更新于 2026年6月 | ✍️ 原创文章,转载请注明出处
1. 设计模式概述
1.1 什么是设计模式
设计模式是解决特定问题的通用方案,经过无数开发者验证的最佳实践。
1.2 三大分类
| 类别 | 目的 | 包含模式 |
|---|---|---|
| 创建型 | 创建对象 | 单例、工厂、建造者、原型 |
| 结构型 | 组合对象 | 适配器、装饰器、代理、外观、桥接 |
| 行为型 | 对象协作 | 策略、观察者、模板方法、责任链、状态 |
1.3 设计原则 (SOLID)
| 原则 | 含义 |
|---|---|
| S 单一职责 | 一个类只做一件事 |
| O 开闭原则 | 对扩展开放,对修改关闭 |
| L 里氏替换 | 子类可以替换父类 |
| I 接口隔离 | 接口要小而专一 |
| D 依赖倒置 | 依赖抽象而非具体 |
2. 单例模式
2.1 适用场景
- 全局配置管理
- 数据库连接池
- 日志记录器
2.2 实现方式
① 饿汉式(推荐)
java
public class Singleton {
// 类加载时就创建
private static final Singleton INSTANCE = new Singleton();
private Singleton() {} // 私有构造器
public static Singleton getInstance() {
return INSTANCE;
}
}
② 懒汉式(双重检查锁)
java
public class Singleton {
private static volatile Singleton instance; // volatile防止指令重排
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton();
}
}
}
return instance;
}
}
③ 静态内部类(推荐)
java
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE; // 首次调用时才加载Holder类
}
}
④ 枚举(最安全)
java
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Working...");
}
}
// 使用
Singleton.INSTANCE.doSomething();
2.3 JDK中的单例
| 类 | 方式 |
|---|---|
Runtime.getRuntime() |
饿汉式 |
Desktop.getDesktop() |
懒汉式 |
3. 工厂模式
3.1 简单工厂
java
public class ShapeFactory {
public static Shape create(String type) {
switch (type.toLowerCase()) {
case "circle": return new Circle();
case "rectangle": return new Rectangle();
case "triangle": return new Triangle();
default: throw new IllegalArgumentException("Unknown shape: " + type);
}
}
}
// 使用
Shape circle = ShapeFactory.create("circle");
3.2 工厂方法
java
// 抽象工厂
public interface ShapeFactory {
Shape create();
}
// 具体工厂
public class CircleFactory implements ShapeFactory {
@Override
public Shape create() {
return new Circle();
}
}
public class RectangleFactory implements ShapeFactory {
@Override
public Shape create() {
return new Rectangle();
}
}
// 使用
ShapeFactory factory = new CircleFactory();
Shape shape = factory.create();
3.3 JDK中的工厂
| 类 | 工厂方法 |
|---|---|
Calendar.getInstance() |
简单工厂 |
Collections.unmodifiableList() |
简单工厂 |
ExecutorService.newFixedThreadPool() |
工厂方法 |
Stream.of() |
静态工厂 |
4. 策略模式
4.1 定义
定义一系列算法,把它们封装起来,使它们可以互相替换。
4.2 实现
java
// 策略接口
public interface SortStrategy<T> {
void sort(List<T> list);
}
// 具体策略
public class BubbleSortStrategy<T extends Comparable<T>> implements SortStrategy<T> {
@Override
public void sort(List<T> list) {
// 冒泡排序实现
}
}
public class QuickSortStrategy<T extends Comparable<T>> implements SortStrategy<T> {
@Override
public void sort(List<T> list) {
// 快速排序实现
}
}
// 上下文
public class Sorter<T extends Comparable<T>> {
private SortStrategy<T> strategy;
public Sorter(SortStrategy<T> strategy) {
this.strategy = strategy;
}
public void setStrategy(SortStrategy<T> strategy) {
this.strategy = strategy;
}
public void sort(List<T> list) {
strategy.sort(list);
}
}
// 使用
Sorter<Integer> sorter = new Sorter<>(new BubbleSortStrategy<>());
sorter.sort(numbers);
// 切换策略
sorter.setStrategy(new QuickSortStrategy<>());
sorter.sort(numbers);
4.3 Lambda简化
java
// 用Lambda替代策略接口
public class Sorter<T extends Comparable<T>> {
private Consumer<List<T>> strategy;
public Sorter(Consumer<List<T>> strategy) {
this.strategy = strategy;
}
public void sort(List<T> list) {
strategy.accept(list);
}
}
// 使用Lambda
Sorter<Integer> sorter = new Sorter<>(list -> {
// 自定义排序逻辑
list.sort(Comparator.naturalOrder());
});
4.4 JDK中的策略
| 类 | 策略 |
|---|---|
Comparator |
排序策略 |
ThreadLocal |
线程隔离策略 |
ThreadPoolExecutor |
拒绝策略 |
5. 观察者模式
5.1 定义
当对象状态变化时,自动通知所有依赖它的对象。
5.2 实现
java
// 观察者接口
public interface Observer {
void update(String event);
}
// 被观察者
public class EventBus {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void unsubscribe(Observer observer) {
observers.remove(observer);
}
public void publish(String event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
// 具体观察者
public class Logger implements Observer {
@Override
public void update(String event) {
System.out.println("[LOG] " + event);
}
}
public class EmailNotifier implements Observer {
@Override
public void update(String event) {
System.out.println("[EMAIL] New event: " + event);
}
}
// 使用
EventBus bus = new EventBus();
bus.subscribe(new Logger());
bus.subscribe(new EmailNotifier());
bus.publish("User registered");
5.3 JDK中的观察者
| 类 | 说明 |
|---|---|
java.util.Observer |
已废弃(不推荐) |
EventListener |
Swing/JavaFX事件 |
Flow.Publisher/Subscriber |
Reactive Streams (Java 9+) |
6. 模板方法模式
6.1 定义
定义算法骨架,将某些步骤延迟到子类实现。
6.2 实现
java
public abstract class DataMiner {
// 模板方法(final防止子类覆盖)
public final void mine() {
openFile();
extractData();
parseData();
analyzeData();
closeFile();
}
// 公共步骤
private void openFile() {
System.out.println("Opening file...");
}
private void closeFile() {
System.out.println("Closing file...");
}
// 抽象步骤(子类必须实现)
protected abstract void extractData();
protected abstract void parseData();
// 钩子方法(子类可选覆盖)
protected void analyzeData() {
System.out.println("Default analysis...");
}
}
// 子类实现
public class CsvMiner extends DataMiner {
@Override
protected void extractData() {
System.out.println("Extracting CSV data...");
}
@Override
protected void parseData() {
System.out.println("Parsing CSV...");
}
}
public class JsonMiner extends DataMiner {
@Override
protected void extractData() {
System.out.println("Extracting JSON data...");
}
@Override
protected void parseData() {
System.out.println("Parsing JSON...");
}
@Override
protected void analyzeData() {
System.out.println("JSON-specific analysis...");
}
}
6.3 JDK中的模板方法
| 类 | 模板方法 |
|---|---|
AbstractList |
get(), size() |
AbstractMap |
entrySet() |
HttpServlet |
doGet(), doPost() |
InputStream |
read() |
7. 建造者模式
7.1 定义
将复杂对象的构建与表示分离,适合多参数对象创建。
7.2 实现
java
public class HttpRequest {
private final String url;
private final String method;
private final Map<String, String> headers;
private final String body;
private final int timeout;
private HttpRequest(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers;
this.body = builder.body;
this.timeout = builder.timeout;
}
public static class Builder {
private String url;
private String method = "GET";
private Map<String, String> headers = new HashMap<>();
private String body;
private int timeout = 30000;
public Builder(String url) {
this.url = url;
}
public Builder method(String method) {
this.method = method;
return this;
}
public Builder header(String key, String value) {
this.headers.put(key, value);
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder timeout(int timeout) {
this.timeout = timeout;
return this;
}
public HttpRequest build() {
return new HttpRequest(this);
}
}
}
// 使用
HttpRequest request = new HttpRequest.Builder("https://api.example.com")
.method("POST")
.header("Content-Type", "application/json")
.body("{\"key\": \"value\"}")
.timeout(5000)
.build();
7.3 JDK中的建造者
| 类 | 建造者 |
|---|---|
StringBuilder |
append() 链式调用 |
Stream.Builder |
add() 构建流 |
HttpClient.Builder |
构建HTTP客户端 |
Locale.Builder |
构建Locale |
8. 适配器模式
8.1 定义
将一个类的接口转换成客户期望的另一个接口。
8.2 实现
java
// 旧接口
public interface OldLogger {
void writeLog(String message);
}
// 新接口
public interface NewLogger {
void info(String message);
void error(String message);
}
// 适配器
public class LoggerAdapter implements NewLogger {
private OldLogger oldLogger;
public LoggerAdapter(OldLogger oldLogger) {
this.oldLogger = oldLogger;
}
@Override
public void info(String message) {
oldLogger.writeLog("[INFO] " + message);
}
@Override
public void error(String message) {
oldLogger.writeLog("[ERROR] " + message);
}
}
8.3 JDK中的适配器
| 适配器 | 作用 |
|---|---|
InputStreamReader |
字节流 → 字符流 |
Arrays.asList() |
数组 → List |
Collections.enumeration() |
Iterator → Enumeration |
9. 装饰器模式
9.1 定义
动态地给对象添加额外职责,比继承更灵活。
9.2 实现
java
// 组件接口
public interface DataSource {
void writeData(String data);
String readData();
}
// 基础实现
public class FileDataSource implements DataSource {
private String filename;
public FileDataSource(String filename) {
this.filename = filename;
}
@Override
public void writeData(String data) {
System.out.println("Writing to file: " + data);
}
@Override
public String readData() {
System.out.println("Reading from file");
return "data";
}
}
// 装饰器基类
public abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappee;
public DataSourceDecorator(DataSource source) {
this.wrappee = source;
}
}
// 加密装饰器
public class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) {
super(source);
}
@Override
public void writeData(String data) {
String encrypted = encrypt(data);
wrappee.writeData(encrypted);
}
@Override
public String readData() {
String data = wrappee.readData();
return decrypt(data);
}
private String encrypt(String data) {
return Base64.getEncoder().encodeToString(data.getBytes());
}
private String decrypt(String data) {
return new String(Base64.getDecoder().decode(data));
}
}
// 压缩装饰器
public class CompressionDecorator extends DataSourceDecorator {
public CompressionDecorator(DataSource source) {
super(source);
}
@Override
public void writeData(String data) {
String compressed = "[COMPRESSED]" + data;
wrappee.writeData(compressed);
}
@Override
public String readData() {
String data = wrappee.readData();
return data.replace("[COMPRESSED]", "");
}
}
// 使用:动态组合功能
DataSource source = new FileDataSource("data.txt");
DataSource encrypted = new EncryptionDecorator(source);
DataSource compressed = new CompressionDecorator(encrypted);
compressed.writeData("Hello World");
// 先压缩 → 再加密 → 写入文件
9.3 JDK中的装饰器
| 装饰器 | 被装饰 |
|---|---|
BufferedInputStream |
InputStream |
BufferedReader |
Reader |
Collections.unmodifiableList() |
List |
Collections.synchronizedList() |
List |
10. 总结
| 模式 | 类型 | 核心思想 | JDK示例 |
|---|---|---|---|
| 单例 | 创建型 | 全局唯一实例 | Runtime |
| 工厂 | 创建型 | 封装对象创建 | Calendar.getInstance() |
| 策略 | 行为型 | 算法可替换 | Comparator |
| 观察者 | 行为型 | 状态变化通知 | EventListener |
| 模板方法 | 行为型 | 算法骨架固定 | AbstractList |
| 建造者 | 创建型 | 复杂对象构建 | StringBuilder |
| 适配器 | 结构型 | 接口转换 | InputStreamReader |
| 装饰器 | 结构型 | 动态添加功能 | BufferedInputStream |
💬 你在项目中用过哪些设计模式?有没有因为没用设计模式导致代码难以维护的经历?
📌 下一篇我们将深入 JVM 内存模型与垃圾回收,理解Java程序的运行原理!