33 设计模式精讲

目录

  • [🟠 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程序的运行原理!


📚 参考资料

相关推荐
码语智行1 小时前
基于word模板导出人员信息
java
西凉的悲伤1 小时前
redis和数据库实现分布式锁
java·数据库·redis·分布式
weixin_523185321 小时前
Java内存模型详解:栈、堆、方法区、本地方法栈与程序计数器
java·开发语言
ywl4708120871 小时前
泛型extends和super的区别
java
惜缘破军2 小时前
基于 Spring Boot 4 和 Spring Cloud 2025 的微服务基础框架 hdfk7-boot
java
小白起 v2 小时前
从零搭建一个现代化的验证码登录系统:Spring Boot + 阿里云短信实战教程
java·阿里云
未若君雅裁2 小时前
工厂模式详解:简单工厂、工厂方法与抽象工厂
java·开发语言
不会写DN2 小时前
通过php 中的Route:: 的写法了解什么是静态类调用
android·java·php