Java 设计模式详解
目录
一、为什么需要设计模式
在 Java 项目中,随着业务复杂度上升,常见问题包括:
if-else / switch急剧膨胀- 类职责不清,修改一处牵一片
- 新需求只能“复制 + 魔改”
- 单元测试困难
- 代码“能跑但不敢动”
设计模式的本质不是语法技巧,而是“解耦变化”的经验总结。
一句话总结:
设计模式 = 封装变化 + 降低耦合 + 提高可扩展性
二、设计模式的理论基础(非常重要)
1. 面向对象六大原则(SOLID)
| 原则 | 含义 |
|---|---|
| SRP | 单一职责 |
| OCP | 对扩展开放,对修改关闭 |
| LSP | 里氏替换 |
| ISP | 接口隔离 |
| DIP | 依赖倒置 |
| 合成复用 | 少继承,多组合 |
设计模式 = SOLID 原则的具体实现形式
三、创建型模式(Creational Patterns)
关注点:对象如何创建,如何解耦“创建”与“使用”
1.单例模式(Singleton)
1.1 业务场景
- 配置中心
- 全局缓存
- 线程池
- Spring 默认 Bean
1.2 双重检查锁(DCL)
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } 关键点解析
volatile:防止指令重排- 第一次 if:减少锁竞争
- 第二次 if:保证线程安全
1.3 最优解(枚举)
public enum Singleton { INSTANCE; } - 防反射
- 防序列化
- JVM 层面保证
2.工厂方法模式(Factory Method)
2.1 解决什么问题?
- 直接
new导致高耦合 - 创建逻辑分散
2.2 示例
interface Payment { void pay(); } class AliPay implements Payment { public void pay() { System.out.println("支付宝支付"); } } class WeChatPay implements Payment { public void pay() { System.out.println("微信支付"); } } class PaymentFactory { static Payment create(String type) { switch (type) { case "ALI": return new AliPay(); case "WX": return new WeChatPay(); default: throw new IllegalArgumentException(); } } } 2.3 反模式提醒
- 工厂里
switch越来越大 → 应升级为策略 + 工厂
3.抽象工厂模式(Abstract Factory)
3.1 典型场景
- 一个“产品族”
- 不同数据库(MySQL / Oracle)
- 不同 UI 风格
interface DaoFactory { UserDao createUserDao(); OrderDao createOrderDao(); } 4.建造者模式(Builder)
4.1 解决问题
- 构造函数参数爆炸
- 可读性差
- 易传错参数
User user = User.builder() .id(1) .name("Tom") .age(18) .email("[email protected]") .build(); Lombok 的 @Builder 就是建造者模式
5.原型模式(Prototype)
5.1 场景
- 对象创建成本高
- 配置对象复制
class Config implements Cloneable { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } 四、结构型模式(Structural Patterns)
关注点:类或对象如何组合,如何解耦结构
6.代理模式(Proxy)【重点】
6.1 场景
- AOP
- 权限校验
- 日志
- 事务
6.2 JDK 动态代理
Object proxy = Proxy.newProxyInstance( clazz.getClassLoader(), clazz.getInterfaces(), (proxy, method, args) -> { System.out.println("before"); Object result = method.invoke(target, args); System.out.println("after"); return result; } ); Spring AOP = 动态代理
7.装饰器模式(Decorator)
7.1 核心思想
在不修改原类的情况下,增强功能
InputStream in = new BufferedInputStream( new FileInputStream("a.txt")); IO 流体系 = 装饰器模式教科书
8.适配器模式(Adapter)
8.1 场景
- 老接口不兼容
- 第三方 SDK 接入
class Adapter implements Target { private Adaptee adaptee; public void request() { adaptee.oldRequest(); } } 9.外观模式(Facade)
9.1 场景
- 封装复杂子系统
- 对外提供简单入口
JdbcTemplate = Facade 10.桥接模式(Bridge)
10.1 解决问题
- 多维度变化
- 避免类爆炸
11.组合模式(Composite)
11.1 场景
- 树形结构
- 菜单 / 组织架构
12.享元模式(Flyweight)
12.1 场景
- 大量细粒度对象
- 缓存复用
String s = "abc"; // 字符串常量池 五、行为型模式(Behavioral Patterns)
关注点:对象之间如何协作、职责如何分配
13.策略模式(Strategy)【非常重要】
13.1 场景
- 支付方式
- 排序算法
- 风控规则
interface Strategy { void execute(); } Map<String, Strategy> strategyMap; - Spring + 策略 = 干掉 if-else
14.模板方法模式(Template Method)
abstract class AbstractService { public final void process() { validate(); execute(); } } -
JdbcTemplate
15.观察者模式(Observer)
- 事件监听
- 发布订阅
ApplicationEventPublisher 16.责任链模式(Chain)
场景
- 审批流
- Filter
- 拦截器
FilterChain 17.状态模式(State)
- 订单状态
- 工作流引擎
18.命令模式(Command)
- 操作封装
- 撤销 / 重做
19.迭代器模式(Iterator)
Iterator<E> 20.备忘录模式(Memento)
- 快照
- 回滚
21.访问者模式(Visitor)
- 编译器
- 复杂结构遍历
22.中介者模式(Mediator)
- 消息中心
- 解耦多对象通信
23.解释器模式(Interpreter)
- 规则引擎
- 表达式解析
六、Spring 中的设计模式总结
| Spring 组件 | 使用的设计模式 |
|---|---|
| BeanFactory | 工厂 |
| ApplicationContext | 单例 |
| AOP | 代理 |
| JdbcTemplate | 模板方法 |
| Event | 观察者 |
| HandlerMapping | 策略 |
| FilterChain | 责任链 |