🎨 设计模式详解

23种经典设计模式的深度解析

设计模式分类

GoF 23种设计模式

创建型模式 (5种)

单例模式
工厂方法
抽象工厂
建造者模式
原型模式

结构型模式 (7种)

适配器模式
桥接模式
组合模式
装饰器模式
外观模式
享元模式
代理模式

行为型模式 (11种)

责任链模式
命令模式
解释器模式
迭代器模式
中介者模式
备忘录模式
观察者模式
状态模式
策略模式
模板方法
访问者模式

设计模式使用频率分析

面向对象设计原则

单一职责原则 (SRP)

一个类应该只有一个引起它变化的原因

核心思想

每个类只负责一项职责,降低类的复杂度

开闭原则 (OCP)

对扩展开放,对修改关闭

核心思想

通过扩展来实现变化,而不是修改现有代码

里氏替换原则 (LSP)

子类必须能够替换其基类

核心思想

继承关系中,子类不能改变父类的行为

接口隔离原则 (ISP)

客户端不应该依赖它不需要的接口

核心思想

使用多个专门的接口比使用单一的总接口要好

依赖倒置原则 (DIP)

高层模块不应该依赖低层模块

核心思想

都应该依赖于抽象,抽象不应该依赖于细节

迪米特法则 (LoD)

一个对象应该对其他对象有最少的了解

核心思想

降低类之间的耦合度,提高模块的相对独立性

创建型模式详解

单例模式 (Singleton Pattern)

确保一个类只有一个实例,并提供全局访问点

应用场景

配置管理器

全局配置信息管理

日志记录器

统一的日志输出管理

数据库连接池

管理数据库连接资源

线程池

管理线程资源

实现方式

懒汉式

延迟初始化,线程安全需要考虑

饿汉式

类加载时初始化,线程安全

双重检查锁

性能优化的线程安全实现

枚举实现

最简洁的实现方式

工厂模式 (Factory Pattern)

创建对象的接口,让子类决定实例化哪个类

简单工厂

一个工厂类负责创建所有产品

优点:简单易用
缺点:违反开闭原则

工厂方法

每个产品对应一个工厂类

优点:符合开闭原则
缺点:类的数量增加

抽象工厂

创建一系列相关的产品族

优点:产品族一致性
缺点:扩展产品困难

建造者模式 (Builder Pattern)

将复杂对象的构建过程与其表示分离

核心组件

Product

要构建的复杂产品

Builder

抽象建造者接口

ConcreteBuilder

具体建造者实现

Director

指挥者,控制构建过程

适用场景

复杂对象创建

对象有很多可选参数

SQL查询构建

动态构建复杂查询

配置对象

系统配置参数设置

结构型模式详解

适配器模式 (Adapter Pattern)

将一个类的接口转换成客户希望的另一个接口

两种实现方式

对象适配器

使用组合关系

  • • 适配器持有被适配者的引用
  • • 运行时动态组合
  • • 更灵活,符合组合优于继承
类适配器

使用继承关系

  • • 适配器继承被适配者
  • • 编译时静态绑定
  • • 可以重写被适配者的方法

典型应用场景

第三方库集成

适配不同的API接口

数据格式转换

XML与JSON格式互转

遗留系统集成

新旧系统接口适配

数据库驱动

统一数据库访问接口

装饰器模式 (Decorator Pattern)

动态地给对象添加一些额外的职责

核心思想

通过包装对象来扩展功能

  • • 不改变原有对象结构
  • • 可以动态添加功能
  • • 可以组合多个装饰器

应用实例

  • • Java I/O流
  • • Spring AOP
  • • Web中间件
  • • 缓存装饰
  • • 日志装饰

优缺点

优点:
  • • 比继承更灵活
  • • 可以动态组合
缺点:
  • • 增加系统复杂性
  • • 多层装饰调试困难

代理模式 (Proxy Pattern)

为其他对象提供一种代理以控制对这个对象的访问

🛡️

保护代理

控制访问权限

🚀

虚拟代理

延迟加载对象

🌐

远程代理

访问远程对象

💾

缓存代理

缓存计算结果

行为型模式详解

观察者模式 (Observer Pattern)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都得到通知

核心角色

Subject (主题)

被观察的对象,维护观察者列表

Observer (观察者)

定义更新接口

ConcreteSubject

具体主题实现

ConcreteObserver

具体观察者实现

应用场景

MVC架构

Model变化通知View更新

事件系统

GUI事件处理机制

消息队列

发布-订阅模式

数据绑定

数据变化自动更新UI

策略模式 (Strategy Pattern)

定义一系列算法,把它们一个个封装起来,并且使它们可相互替换

核心组件

Context: 上下文类
Strategy: 策略接口
ConcreteStrategy: 具体策略

应用实例

  • • 排序算法选择
  • • 支付方式选择
  • • 压缩算法选择
  • • 验证策略
  • • 折扣计算

优势

  • • 避免多重条件判断
  • • 算法可以自由切换
  • • 扩展性好
  • • 符合开闭原则

模板方法模式 (Template Method Pattern)

定义一个操作中的算法骨架,而将一些步骤延迟到子类中

方法类型

模板方法

定义算法骨架,final修饰

抽象方法

子类必须实现的方法

钩子方法

子类可选择性重写

具体方法

已实现的通用方法

典型应用

框架设计

Spring、Hibernate等框架

数据处理

ETL数据处理流程

测试框架

JUnit测试生命周期

工作流引擎

业务流程模板

设计模式代码示例

单例模式代码实现

饿汉式单例

public class EagerSingleton {
    // 类加载时就创建实例
    private static final EagerSingleton
        INSTANCE = new EagerSingleton();

    // 私有构造函数
    private EagerSingleton() {}

    // 获取实例的静态方法
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}
特点: 线程安全,但可能造成内存浪费

懒汉式单例(双重检查)

public class LazySingleton {
    private static volatile LazySingleton instance;

    private LazySingleton() {}

    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}
特点: 延迟加载,线程安全,性能较好

观察者模式代码实现

接口定义

// 观察者接口
interface Observer {
    void update(String message);
}

// 主题接口
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

具体主题

public class NewsAgency implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String news;

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(news);
        }
    }

    public void setNews(String news) {
        this.news = news;
        notifyObservers();
    }
}

具体观察者

public class NewsChannel implements Observer {
    private String name;

    public NewsChannel(String name) {
        this.name = name;
    }

    @Override
    public void update(String news) {
        System.out.println(name + " 收到新闻: " + news);
    }
}

// 使用示例
NewsAgency agency = new NewsAgency();
NewsChannel cnn = new NewsChannel("CNN");
NewsChannel bbc = new NewsChannel("BBC");

agency.addObserver(cnn);
agency.addObserver(bbc);
agency.setNews("重大新闻发布!");

工厂模式代码实现

简单工厂模式

// 产品接口
interface Shape {
    void draw();
}

// 具体产品
class Circle implements Shape {
    public void draw() {
        System.out.println("绘制圆形");
    }
}

class Rectangle implements Shape {
    public void draw() {
        System.out.println("绘制矩形");
    }
}

// 简单工厂
class ShapeFactory {
    public static Shape createShape(String type) {
        switch (type) {
            case "circle": return new Circle();
            case "rectangle": return new Rectangle();
            default: throw new IllegalArgumentException();
        }
    }
}

抽象工厂模式

// 抽象工厂
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂
class WindowsFactory implements GUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

class MacFactory implements GUIFactory {
    public Button createButton() {
        return new MacButton();
    }
    public TextField createTextField() {
        return new MacTextField();
    }
}