状态模式适用于分支超5–6种、存在明确状态流转、同一操作行为因状态而异或需动态扩展状态的场景;通过状态接口、具体状态类和上下文三角色解耦判断逻辑,提升可读性、可测性与可扩展性。

用状态模式优化 Java 中冗长的选择结构(如一长串 if-else if 或 switch),核心是把“条件判断逻辑”从主流程中剥离,转为由对象状态驱动行为。这不是为了炫技,而是当分支逻辑变多、状态有生命周期、或分支间存在流转关系时,能让代码更易读、可测、可扩展。
什么时候该考虑状态模式替代选择结构
以下情况直接用 if/switch 没问题;但一旦出现其中 2 条以上,就值得评估状态模式:
- 分支超过 5–6 种,且每种分支内含多行业务逻辑(比如校验、赋值、发消息)
- 不同分支之间存在明确的状态流转(例如:待提交 → 审核中 → 已通过 → 已归档)
- 同一操作在不同状态下行为不同(如点击“确认”按钮,在“待提交”时保存,在“审核中”时提示“不可修改”)
- 后续可能新增状态,或需要动态切换状态策略(如按租户启用不同审批规则)
状态模式的最小可行结构
不需复杂框架,3 个核心角色即可落地:
-
状态接口:定义所有状态共有的行为方法(如
handle()、onEnter()) - 具体状态类:每个实现类封装一种状态下的完整逻辑(把原来 if 块里的代码搬进来)
-
上下文类:持有当前状态引用,对外提供统一入口方法(如
process()),内部委托给当前状态执行
关键点:上下文不写任何 if 判断;状态切换由具体状态类决定(比如 ApprovedState 执行完后调用 context.setState(new ArchivedState()))。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
一个真实感强的简化示例
假设处理订单状态,原代码可能是:
if ("draft".equals(order.getStatus())) {
order.setStatus("submitted");
notifySubmit(order);
} else if ("submitted".equals(order.getStatus())) {
if (order.isValid()) {
order.setStatus("approved");
sendApprovalMsg(order);
} else {
order.setStatus("rejected");
sendRejectMsg(order);
}
} else if ("approved".equals(order.getStatus())) {
shipOrder(order);
order.setStatus("shipped");
}
改用状态模式后:
- 定义
OrderState接口,含process(OrderContext ctx) - 实现
DraftState、SubmittedState、ApprovedState,各自封装对应逻辑 -
OrderContext只维护state字段和process()方法,调用state.process(this) - 状态切换在具体类中完成:
ctx.setState(new ApprovedState())
后续加“退货中”状态?只需新增一个状态类,不碰原有代码,也不改 OrderContext。
注意避开两个典型误区
状态模式不是银弹,用错反而增加复杂度:
-
别把无流转关系的纯枚举分支硬套状态模式——比如根据用户等级(VIP/普通/游客)展示不同头像边框,用
switch(userLevel)更直白 - 状态类之间不要互相强依赖或循环调用——用上下文作为中介协调,保持单向依赖(状态 → 上下文,上下文 → 状态)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










