2026年7月11日 · 5 分钟阅读
Java 行为型设计模式:流程、状态、通知与职责流转
系统梳理行为型设计模式的核心思想,包括模板方法、命令、观察者、状态、策略、职责链等模式。
行为型模式关注对象之间的职责分配和流程控制。
如果代码里出现大量 if/else、状态判断、通知分发、流程编排、算法切换,通常就要考虑行为型模式。
模板方法模式
模板方法模式把流程骨架放在父类中,把可变步骤交给子类实现。
public abstract class DataImporter {
public final void importData() {
read();
validate();
save();
}
protected abstract void read();
protected abstract void validate();
protected abstract void save();
}
适合流程固定、步骤可变的场景,例如导入文件、审批流程、报表生成。
命令模式
命令模式把请求封装成对象,从而支持排队、撤销、日志记录和异步执行。
public interface Command {
void execute();
}
public class CreateOrderCommand implements Command {
public void execute() {
System.out.println("create order");
}
}
命令模式适合任务调度、操作记录、批处理、消息队列消费。
访问者模式
访问者模式把作用于对象结构上的操作抽离出来,使新增操作不需要修改对象结构。
它适合对象结构稳定、操作经常变化的场景。
典型场景:
- 编译器 AST 遍历。
- 报表统计。
- 对不同节点执行不同操作。
访问者模式类较多,普通业务系统中要谨慎使用。
迭代器模式
迭代器模式提供统一遍历方式,不暴露集合内部结构。
Java 集合框架里的 Iterator 就是典型例子。
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
业务中如果自定义集合结构,也可以提供迭代器隐藏内部存储细节。
观察者模式
观察者模式用于一对多通知。当一个对象状态变化时,自动通知多个观察者。
public interface Observer {
void update(String event);
}
public class EventPublisher {
private final List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void publish(String event) {
observers.forEach(observer -> observer.update(event));
}
}
典型场景:
- 事件发布订阅。
- 消息通知。
- 缓存刷新。
- 领域事件。
观察者模式要注意异常隔离。一个观察者失败,不应该影响所有观察者。
中介者模式
中介者模式通过中介对象封装多个对象之间的复杂交互。
如果多个对象互相调用,依赖关系像网一样复杂,可以引入中介者统一协调。
典型场景:
- UI 控件联动。
- 聊天室。
- 工作流协调。
中介者模式能降低对象之间的直接依赖,但中介者本身可能变得臃肿,需要控制职责边界。
备忘录模式
备忘录模式用于保存对象历史状态,并在需要时恢复。
典型场景:
- 撤销操作。
- 草稿保存。
- 游戏存档。
- 配置回滚。
备忘录模式要注意存储成本。如果对象状态很大,需要考虑增量保存或快照压缩。
解释器模式
解释器模式用于定义语言文法,并解释表达式。
典型场景:
- 表达式计算。
- 规则引擎。
- SQL / DSL 解析。
- Spring Expression Language 这类表达式解析。
解释器模式适合语法稳定、规则可抽象的场景。如果规则复杂,通常会演变成完整解析器或规则引擎。
状态模式
状态模式把不同状态下的行为封装到不同状态类中,避免大量状态判断。
例如订单有待支付、已支付、已取消、已完成等状态,不同状态下可执行操作不同。
public interface OrderState {
void pay(OrderContext context);
void cancel(OrderContext context);
}
public class PendingState implements OrderState {
public void pay(OrderContext context) {
context.setState(new PaidState());
}
public void cancel(OrderContext context) {
context.setState(new CanceledState());
}
}
状态模式适合状态多、状态转换复杂、不同状态行为差异明显的场景。
策略模式
策略模式把一组算法封装起来,使它们可以互相替换。
public interface DiscountStrategy {
int discount(int amount);
}
public class VipDiscount implements DiscountStrategy {
public int discount(int amount) {
return amount * 80 / 100;
}
}
典型场景:
- 支付方式。
- 折扣规则。
- 排序算法。
- 文件解析策略。
策略模式和状态模式很像。区别是:策略通常由外部选择,状态通常由对象内部状态流转决定。
职责链模式
职责链模式把多个处理器串成链,请求沿链传递,直到被处理或链结束。
public abstract class Handler {
private Handler next;
public Handler setNext(Handler next) {
this.next = next;
return next;
}
public final void handle(Request request) {
if (doHandle(request) && next != null) {
next.handle(request);
}
}
protected abstract boolean doHandle(Request request);
}
典型场景:
- 审批流。
- 网关过滤器。
- 参数校验链。
- 日志处理链。
职责链要注意链路顺序和中断条件,否则问题排查会变困难。
行为型模式选择建议
| 场景 | 推荐模式 |
|---|---|
| 流程固定,步骤变化 | 模板方法 |
| 请求需要封装、排队、撤销 | 命令 |
| 对象结构稳定,操作变化 | 访问者 |
| 隐藏集合遍历细节 | 迭代器 |
| 一对多事件通知 | 观察者 |
| 多对象复杂交互 | 中介者 |
| 保存和恢复历史状态 | 备忘录 |
| 解析表达式或 DSL | 解释器 |
| 状态驱动行为变化 | 状态 |
| 算法可替换 | 策略 |
| 多处理器链式处理 | 职责链 |
小结
行为型模式的核心是把流程、状态、通知、算法和职责链从业务主体中拆出来。
当业务代码开始被大量条件判断淹没时,通常就是行为型模式登场的时候。