常见设计模式总结

设计模式是解决软件设计中高频问题的成熟方案,按核心功能可分为创建型结构型行为型三大类,以下是各类别中最常用的设计模式解析。

一、创建型模式

核心目标:隐藏对象创建细节,控制对象实例化过程,提高代码灵活性与复用性。

1. 单例模式(Singleton)

  • 核心思想:保证一个类在全局范围内仅有一个实例,并提供统一的访问入口。
  • 典型场景:线程池、配置管理器、日志工具类、java.lang.Runtime 类。
  • 实现关键:私有化构造方法,通过静态方法/静态内部类返回唯一实例(需注意线程安全,如双重检查锁)。
  • 优势:避免重复创建对象,节约内存资源;避免多实例导致的状态不一致。

2. 工厂模式(Factory)

  • 核心思想:通过工厂类统一负责对象创建,替代直接 new 操作,实现“创建与使用分离”。
  • 细分类型
    • 简单工厂:一个工厂类根据参数(如字符串、枚举)创建不同产品实例(如计算器工厂创建加减乘除对象)。
    • 工厂方法:为每个产品类单独定义对应的工厂类(如 MySQL 连接工厂、Oracle 连接工厂)。
  • 典型场景:JDBC 的 DriverManager 创建数据库连接、框架中的 Bean 实例创建。
  • 优势:降低代码耦合,切换产品时无需修改使用方代码(符合“开闭原则”)。

3. 建造者模式(Builder)

  • 核心思想:将复杂对象的构造过程拆分为多个步骤,通过建造者类逐步组装,最终生成对象。
  • 典型场景:创建参数多且部分可选的对象(如 StringBuilder、Lombok 的 @Builder 注解、复杂配置类)。
  • 优势:避免“ telescoping constructor ”(长参数构造器)的混乱,提高代码可读性;支持灵活配置对象属性。

二、结构型模式

核心目标:优化类或对象的组合方式,解决类/对象间的结构适配问题,提高代码扩展性。

1. 代理模式(Proxy)

  • 核心思想:为目标对象创建一个“代理对象”,通过代理对象间接访问目标对象,实现对目标对象的控制(如权限校验、日志记录、远程调用)。
  • 细分类型
    • 静态代理:编译期确定代理类,代理逻辑固定。
    • 动态代理:运行时动态生成代理类(如 JDK 动态代理、CGLIB 代理)。
  • 典型场景:Spring AOP(方法增强)、RPC 框架(远程服务代理)、权限控制。
  • 优势:不修改目标对象代码即可扩展功能(符合“开闭原则”)。

2. 装饰器模式(Decorator)

  • 核心思想:通过“装饰类”动态为目标对象添加新功能,且不改变目标对象的原有结构,支持多层装饰。
  • 典型场景:Java IO 流(如 BufferedReader 装饰 Reader 增加缓冲功能、DataInputStream 装饰 InputStream 增加数据类型读取功能)、日志增强。
  • 优势:比继承更灵活(可组合多个装饰功能),避免类爆炸问题。

3. 适配器模式(Adapter)

  • 核心思想:将一个类的接口转换成客户端期望的另一种接口,解决“接口不兼容”问题(如旧系统接口适配新系统、第三方库接口适配自定义接口)。
  • 细分类型
    • 类适配器:通过继承适配源类实现。
    • 对象适配器:通过持有适配源对象实现(更常用)。
  • 典型场景:JDBC 驱动(适配不同数据库的底层接口到 JDBC 标准接口)、旧接口改造。
  • 优势:复用现有代码,降低系统改造成本,解决兼容性问题。

三、行为型模式

核心目标:定义对象间的交互方式与职责分配,优化对象通信流程,提高代码可维护性。

1. 观察者模式(Observer)

  • 核心思想:定义“一对多”的依赖关系,当“被观察者”(主题)状态变化时,自动通知所有“观察者”并触发其更新操作。
  • 典型场景:GUI 事件监听(如按钮点击事件)、消息订阅/发布(如 MQ 的发布-订阅模式)、java.util.ObserverObservable 实现。
  • 优势:解耦被观察者与观察者,支持动态添加/移除观察者。

2. 策略模式(Strategy)

  • 核心思想:定义一系列算法(策略),将每个算法封装为独立类,使算法可动态切换,替代大量 if-else 判断。
  • 典型场景:支付方式选择(微信支付、支付宝支付、银联支付)、排序算法切换、折扣计算逻辑。
  • 优势:算法可独立扩展,切换算法时无需修改使用方代码(符合“开闭原则”)。

3. 模板方法模式(Template Method)

  • 核心思想:在父类中定义算法的“骨架”(固定步骤),将算法中的可变步骤延迟到子类中实现,确保算法结构不变。
  • 典型场景:框架设计(如 Spring 的 JdbcTemplate 固定数据库操作流程,子类仅需实现 SQL 执行与结果映射)、报表生成(固定格式,数据填充逻辑可变)。
  • 优势:复用算法骨架,子类聚焦可变逻辑,避免代码重复。

4. 迭代器模式(Iterator)

  • 核心思想:提供一种统一的接口遍历集合对象中的元素,无需暴露集合的内部存储结构(如数组、链表)。
  • 典型场景:Java 集合框架(ArrayListHashMap 等的 iterator() 方法)、自定义集合类的遍历。
  • 优势:遍历逻辑与集合结构解耦,支持多种遍历方式(如正向、反向)。