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解释器
状态驱动行为变化状态
算法可替换策略
多处理器链式处理职责链

小结

行为型模式的核心是把流程、状态、通知、算法和职责链从业务主体中拆出来。

当业务代码开始被大量条件判断淹没时,通常就是行为型模式登场的时候。