一、核心概念
状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。
设计思想
- 状态驱动行为:将对象的行为封装在不同的状态类中
- 消除条件分支:用多态替换复杂的条件判断语句
- 状态转换:在状态内部定义状态转换逻辑
- 开闭原则:新增状态不影响现有代码
二、模式结构
类图示意
复制
┌─────────────────┐ ┌───────────────┐
│ Context │────────▶│ State │
│ (上下文) │ │ (状态接口) │
├─────────────────┤ ├───────────────┤
│ -state: State │ │ +handle() │
│ +setState() │ └───────────────┘
│ +request() │ △
└─────────────────┘ │
│ ┌────────────┴────────────┐
│ │ │
│ ┌─────────────────┐ ┌─────────────────┐
│ │ ConcreteStateA │ │ ConcreteStateB │
│ ├─────────────────┤ ├─────────────────┤
└────│ +handle() │ │ +handle() │
│ +transitionTo() │ │ +transitionTo() │
└─────────────────┘ └─────────────────┘
核心角色
-
Context (上下文)
- 定义客户端感兴趣的接口
- 维护一个ConcreteState子类的实例
- 委托状态相关的行为给当前状态对象
-
State (状态接口)
- 定义一个接口,用于封装与Context的特定状态相关的行为
-
ConcreteState (具体状态)
- 实现与Context的一个状态相关的行为
- 可触发状态转换
三、Java代码实现
基础实现示例
java
java
下载
复制
// 1. 状态接口
public interface OrderState {
void handle(OrderContext context);
String getStatusName();
boolean canCancel();
boolean canPay();
boolean canShip();
}
// 2. 具体状态类
// 新建订单状态
public class NewOrderState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已创建,等待付款");
}
@Override
public String getStatusName() {
return "新建";
}
@Override
public boolean canCancel() {
return true; // 新建订单可以取消
}
@Override
public boolean canPay() {
return true; // 新建订单可以支付
}
@Override
public boolean canShip() {
return false; // 新建订单不能发货
}
@Override
public String toString() {
return "新建订单状态";
}
}
// 已支付状态
public class PaidState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已支付,等待发货");
}
@Override
public String getStatusName() {
return "已支付";
}
@Override
public boolean canCancel() {
return true; // 已支付订单可以取消(但可能涉及退款)
}
@Override
public boolean canPay() {
return false; // 已支付订单不能再次支付
}
@Override
public boolean canShip() {
return true; // 已支付订单可以发货
}
@Override
public String toString() {
return "已支付状态";
}
}
// 已发货状态
public class ShippedState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已发货,运输中");
}
@Override
public String getStatusName() {
return "已发货";
}
@Override
public boolean canCancel() {
return false; // 已发货订单不能取消
}
@Override
public boolean canPay() {
return false; // 已发货订单不能支付
}
@Override
public boolean canShip() {
return false; // 已发货订单不能再次发货
}
@Override
public String toString() {
return "已发货状态";
}
}
// 已完成状态
public class CompletedState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已完成,感谢购买");
}
@Override
public String getStatusName() {
return "已完成";
}
@Override
public boolean canCancel() {
return false; // 已完成订单不能取消
}
@Override
public boolean canPay() {
return false; // 已完成订单不能支付
}
@Override
public boolean canShip() {
return false; // 已完成订单不能发货
}
@Override
public String toString() {
return "已完成状态";
}
}
// 已取消状态
public class CanceledState implements OrderState {
@Override
public void handle(OrderContext context) {
System.out.println("订单已取消");
}
@Override
public String getStatusName() {
return "已取消";
}
@Override
public boolean canCancel() {
return false; // 已取消订单不能再次取消
}
@Override
public boolean canPay() {
return false; // 已取消订单不能支付
}
@Override
public boolean canShip() {
return false; // 已取消订单不能发货
}
@Override
public String toString() {
return "已取消状态";
}
}
// 3. 上下文类
public class OrderContext {
private OrderState currentState;
private String orderId;
private List<String> stateHistory = new ArrayList<>();
public OrderContext(String orderId) {
this.orderId = orderId;
// 初始状态为新建
this.currentState = new NewOrderState();
this.stateHistory.add("订单创建 -> " + currentState.getStatusName());
currentState.handle(this);
}
public void setState(OrderState state) {
System.out.printf("订单状态变更: [%s] -> [%s]%n",
currentState.getStatusName(), state.getStatusName());
this.currentState = state;
this.stateHistory.add(state.getStatusName());
this.currentState.handle(this);
}
public void pay() {
if (currentState.canPay()) {
System.out.println("执行支付操作...");
// 模拟支付处理
setState(new PaidState());
} else {
System.out.println("当前状态[" + currentState.getStatusName() + "]不允许支付");
}
}
public void cancel() {
if (currentState.canCancel()) {
System.out.println("执行取消操作...");
// 模拟取消处理
setState(new CanceledState());
} else {
System.out.println("当前状态[" + currentState.getStatusName() + "]不允许取消");
}
}
public void ship() {
if (currentState.canShip()) {
System.out.println("执行发货操作...");
// 模拟发货处理
setState(new ShippedState());
} else {
System.out.println("当前状态[" + currentState.getStatusName() + "]不允许发货");
}
}
public void complete() {
if (currentState instanceof ShippedState) {
System.out.println("确认收货,订单完成...");
setState(new CompletedState());
} else {
System.out.println("当前状态[" + currentState.getStatusName() + "]不能完成");
}
}
public void returnGoods() {
if (currentState instanceof ShippedState || currentState instanceof CompletedState) {
System.out.println("申请退货...");
// 退货流程
setState(new CanceledState());
} else {
System.out.println("当前状态[" + currentState.getStatusName() + "]不能退货");
}
}
// 状态查询方法
public String getCurrentStatus() {
return currentState.getStatusName();
}
public OrderState getCurrentState() {
return currentState;
}
public List<String> getStateHistory() {
return new ArrayList<>(stateHistory);
}
public String getOrderId() {
return orderId;
}
}
// 4. 状态转换规则(可选,用于管理状态转换逻辑)
public class StateTransitionRules {
private Map<Class<? extends OrderState>, Map<String, Class<? extends OrderState>>> rules = new HashMap<>();
public StateTransitionRules() {
initializeRules();
}
private void initializeRules() {
// 定义状态转换规则
addRule(NewOrderState.class, "pay", PaidState.class);
addRule(NewOrderState.class, "cancel", CanceledState.class);
addRule(PaidState.class, "ship", ShippedState.class);
addRule(PaidState.class, "cancel", CanceledState.class);
addRule(ShippedState.class, "complete", CompletedState.class);
addRule(ShippedState.class, "return", CanceledState.class);
addRule(CompletedState.class, "return", CanceledState.class);
}
private void addRule(Class<? extends OrderState> fromState, String action,
Class<? extends OrderState> toState) {
rules.computeIfAbsent(fromState, k -> new HashMap<>())
.put(action, toState);
}
public Class<? extends OrderState> getNextState(Class<? extends OrderState> currentState, String action) {
Map<String, Class<? extends OrderState>> stateRules = rules.get(currentState);
if (stateRules != null) {
return stateRules.get(action);
}
return null;
}
public boolean canTransition(Class<? extends OrderState> currentState, String action) {
return getNextState(currentState, action) != null;
}
}
// 5. 客户端使用
public class StatePatternDemo {
public static void main(String[] args) {
System.out.println("=== 状态模式演示 - 订单状态管理 ===\n");
// 创建订单
OrderContext order = new OrderContext("ORD001");
System.out.println("订单ID: " + order.getOrderId());
System.out.println("当前状态: " + order.getCurrentStatus());
// 测试状态转换
System.out.println("\n--- 测试正常流程 ---");
order.pay(); // 新建 -> 已支付
order.ship(); // 已支付 -> 已发货
order.complete(); // 已发货 -> 已完成
System.out.println("\n--- 测试非法操作 ---");
order.pay(); // 已完成 -> 不能支付
order.ship(); // 已完成 -> 不能发货
System.out.println("\n--- 测试退货流程 ---");
OrderContext returnOrder = new OrderContext("ORD002");
returnOrder.pay();
returnOrder.ship();
returnOrder.returnGoods(); // 已发货 -> 已取消(退货)
System.out.println("\n--- 状态历史 ---");
System.out.println("订单ORD001状态历史:");
for (String state : order.getStateHistory()) {
System.out.println(" - " + state);
}
// 测试状态规则
testStateTransitionRules();
}
private static void testStateTransitionRules() {
System.out.println("\n=== 状态转换规则测试 ===");
StateTransitionRules rules = new StateTransitionRules();
// 验证规则
System.out.println("新建订单可以支付: " +
rules.canTransition(NewOrderState.class, "pay"));
System.out.println("已支付订单可以发货: " +
rules.canTransition(PaidState.class, "ship"));
System.out.println("已完成订单可以退货: " +
rules.canTransition(CompletedState.class, "return"));
}
}
高级示例:有限状态机(FSM)
java
java
下载
复制
// 1. 状态机接口
public interface StateMachine<S, E> {
S getCurrentState();
void fire(E event);
void addTransition(S fromState, E event, S toState, Runnable action);
void addTransition(S fromState, E event, S toState);
}
// 2. 状态机实现
public class FiniteStateMachine<S, E> implements StateMachine<S, E> {
private S currentState;
private final Map<S, Map<E, Transition<S, E>>> transitions = new HashMap<>();
private final Set<S> states = new HashSet<>();
private final Set<E> events = new HashSet<>();
public FiniteStateMachine(S initialState) {
this.currentState = initialState;
states.add(initialState);
}
@Override
public S getCurrentState() {
return currentState;
}
@Override
public void fire(E event) {
Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
if (stateTransitions == null) {
throw new IllegalStateException("No transitions defined for state: " + currentState);
}
Transition<S, E> transition = stateTransitions.get(event);
if (transition == null) {
throw new IllegalStateException("No transition defined for event: " + event +
" in state: " + currentState);
}
// 执行转换
if (transition.getAction() != null) {
transition.getAction().run();
}
S oldState = currentState;
currentState = transition.getToState();
System.out.printf("状态转换: [%s] --%s--> [%s]%n",
oldState, event, currentState);
}
@Override
public void addTransition(S fromState, E event, S toState, Runnable action) {
states.add(fromState);
states.add(toState);
events.add(event);
transitions.computeIfAbsent(fromState, k -> new HashMap<>())
.put(event, new Transition<>(fromState, event, toState, action));
}
@Override
public void addTransition(S fromState, E event, S toState) {
addTransition(fromState, event, toState, null);
}
public boolean canFire(E event) {
Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
return stateTransitions != null && stateTransitions.containsKey(event);
}
public Set<E> getAvailableEvents() {
Map<E, Transition<S, E>> stateTransitions = transitions.get(currentState);
if (stateTransitions == null) {
return Collections.emptySet();
}
return stateTransitions.keySet();
}
// 转换类
private static class Transition<S, E> {
private final S fromState;
private final E event;
private final S toState;
private final Runnable action;
public Transition(S fromState, E event, S toState, Runnable action) {
this.fromState = fromState;
this.event = event;
this.toState = toState;
this.action = action;
}
public S getFromState() { return fromState; }
public E getEvent() { return event; }
public S getToState() { return toState; }
public Runnable getAction() { return action; }
}
}
// 3. 使用状态机的工作流示例
public class WorkflowStateMachine {
public enum State {
DRAFT, REVIEWING, APPROVED, REJECTED, PUBLISHED, ARCHIVED
}
public enum Event {
SUBMIT, APPROVE, REJECT, PUBLISH, ARCHIVE, REOPEN
}
public static void main(String[] args) {
// 创建状态机
FiniteStateMachine<State, Event> fsm = new FiniteStateMachine<>(State.DRAFT);
// 定义状态转换
fsm.addTransition(State.DRAFT, Event.SUBMIT, State.REVIEWING,
() -> System.out.println("提交文档进入审核流程"));
fsm.addTransition(State.REVIEWING, Event.APPROVE, State.APPROVED,
() -> System.out.println("文档审核通过"));
fsm.addTransition(State.REVIEWING, Event.REJECT, State.REJECTED,
() -> System.out.println("文档审核驳回"));
fsm.addTransition(State.APPROVED, Event.PUBLISH, State.PUBLISHED,
() -> System.out.println("文档已发布"));
fsm.addTransition(State.REJECTED, Event.REOPEN, State.DRAFT,
() -> System.out.println("重新打开文档进行修改"));
fsm.addTransition(State.PUBLISHED, Event.ARCHIVE, State.ARCHIVED,
() -> System.out.println("文档已归档"));
// 执行状态转换
System.out.println("当前状态: " + fsm.getCurrentState());
System.out.println("可用事件: " + fsm.getAvailableEvents());
fsm.fire(Event.SUBMIT);
System.out.println("当前状态: " + fsm.getCurrentState());
System.out.println("可用事件: " + fsm.getAvailableEvents());
fsm.fire(Event.APPROVE);
System.out.println("当前状态: " + fsm.getCurrentState());
System.out.println("可用事件: " + fsm.getAvailableEvents());
fsm.fire(Event.PUBLISH);
System.out.println("当前状态: " + fsm.getCurrentState());
System.out.println("可用事件: " + fsm.getAvailableEvents());
// 测试非法转换
try {
fsm.fire(Event.REJECT); // 应该失败
} catch (IllegalStateException e) {
System.out.println("预期错误: " + e.getMessage());
}
}
}
四、应用场景
1. 订单/工作流系统
java
java
下载
复制
// 复杂的订单状态机
public class ComplexOrderWorkflow {
public enum OrderStateEnum {
CREATED, VALIDATING, PAYMENT_PENDING, PAYMENT_PROCESSING,
PAYMENT_FAILED, PAYMENT_COMPLETED, INVENTORY_CHECKING,
INVENTORY_RESERVED, PACKING, SHIPPING, DELIVERED,
CANCELLED, REFUND_PENDING, REFUNDED, COMPLETED
}
public class OrderStateMachine {
private OrderStateEnum currentState;
private String orderId;
private StateTransitionValidator validator = new StateTransitionValidator();
public void transition(OrderStateEnum newState, Map<String, Object> context) {
if (validator.isValidTransition(currentState, newState, context)) {
OrderStateEnum oldState = currentState;
currentState = newState;
executeStateActions(oldState, newState, context);
logTransition(oldState, newState, context);
} else {
throw new IllegalStateException(
String.format("无效的状态转换: %s -> %s", currentState, newState));
}
}
private void executeStateActions(OrderStateEnum from, OrderStateEnum to,
Map<String, Object> context) {
// 执行进入状态的动作
switch (to) {
case PAYMENT_PROCESSING:
processPayment(context);
break;
case INVENTORY_RESERVED:
reserveInventory(context);
break;
case SHIPPING:
createShippingLabel(context);
break;
case DELIVERED:
sendDeliveryNotification(context);
break;
case REFUNDED:
processRefund(context);
break;
}
// 执行离开状态的动作
switch (from) {
case PAYMENT_PROCESSING:
cleanupPaymentSession(context);
break;
case INVENTORY_RESERVED:
releaseTemporaryHold(context);
break;
}
}
}
}
2. 游戏开发
java
java
下载
复制
// 游戏角色状态
public class GameCharacter {
private CharacterState currentState;
private int health = 100;
private int mana = 50;
public interface CharacterState {
void handleInput(GameCharacter character, String input);
void update(GameCharacter character);
void enter(GameCharacter character);
void exit(GameCharacter character);
String getStateName();
}
public class IdleState implements CharacterState {
@Override
public void handleInput(GameCharacter character, String input) {
switch (input) {
case "WALK":
character.setState(new WalkingState());
break;
case "ATTACK":
character.setState(new AttackingState());
break;
case "CAST":
if (character.mana >= 10) {
character.setState(new CastingState());
}
break;
}
}
@Override
public void update(GameCharacter character) {
// 缓慢恢复生命值和魔法值
character.health = Math.min(100, character.health + 1);
character.mana = Math.min(100, character.mana + 2);
}
}
public class WalkingState implements CharacterState {
@Override
public void handleInput(GameCharacter character, String input) {
if (input.equals("STOP")) {
character.setState(new IdleState());
}
}
@Override
public void update(GameCharacter character) {
// 移动逻辑
}
}
public class AttackingState implements CharacterState {
private int attackCooldown = 0;
@Override
public void handleInput(GameCharacter character, String input) {
if (input.equals("STOP_ATTACK")) {
character.setState(new IdleState());
}
}
@Override
public void update(GameCharacter character) {
if (attackCooldown > 0) {
attackCooldown--;
} else {
// 攻击逻辑
attackCooldown = 20; // 20帧冷却
}
}
}
}
3. 网络连接管理
java
java
下载
复制
// TCP连接状态机
public class TCPConnection {
private TCPState state;
private String remoteAddress;
private int remotePort;
public interface TCPState {
void open(TCPConnection connection);
void close(TCPConnection connection);
void acknowledge(TCPConnection connection);
void send(TCPConnection connection, byte[] data);
TCPStateEnum getState();
}
public enum TCPStateEnum {
CLOSED, LISTEN, SYN_SENT, SYN_RECEIVED,
ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2,
CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT
}
public class ClosedState implements TCPState {
@Override
public void open(TCPConnection connection) {
System.out.println("发送SYN包");
connection.setState(new SynSentState());
}
@Override
public void close(TCPConnection connection) {
// 已经是关闭状态
}
@Override
public void acknowledge(TCPConnection connection) {
throw new IllegalStateException("连接已关闭");
}
@Override
public void send(TCPConnection connection, byte[] data) {
throw new IllegalStateException("连接已关闭,不能发送数据");
}
}
public class EstablishedState implements TCPState {
@Override
public void open(TCPConnection connection) {
throw new IllegalStateException("连接已建立");
}
@Override
public void close(TCPConnection connection) {
System.out.println("发送FIN包");
connection.setState(new FinWait1State());
}
@Override
public void acknowledge(TCPConnection connection) {
// 处理ACK
}
@Override
public void send(TCPConnection connection, byte[] data) {
System.out.println("发送数据: " + data.length + " bytes");
// 实际发送逻辑
}
}
// 其他状态实现...
public void setState(TCPState state) {
System.out.println("TCP连接状态变更: " + this.state + " -> " + state);
this.state = state;
}
public void send(byte[] data) {
state.send(this, data);
}
}
4. UI组件状态
java
java
下载
复制
// 按钮状态管理
public class UIButton {
private ButtonState state;
private String text;
private boolean enabled = true;
private Runnable onClick;
public interface ButtonState {
void render(UIButton button, Graphics2D g);
void handleClick(UIButton button, MouseEvent e);
void handleHover(UIButton button, MouseEvent e);
void handleLeave(UIButton button, MouseEvent e);
void setEnabled(UIButton button, boolean enabled);
}
public class NormalState implements ButtonState {
@Override
public void render(UIButton button, Graphics2D g) {
g.setColor(Color.BLUE);
g.fillRect(0, 0, button.getWidth(), button.getHeight());
g.setColor(Color.WHITE);
g.drawString(button.text, 10, 20);
}
@Override
public void handleClick(UIButton button, MouseEvent e) {
if (button.onClick != null && button.enabled) {
button.setState(new ClickedState());
button.onClick.run();
}
}
@Override
public void handleHover(UIButton button, MouseEvent e) {
button.setState(new HoverState());
}
}
public class HoverState implements ButtonState {
@Override
public void render(UIButton button, Graphics2D g) {
g.setColor(Color.CYAN);
g.fillRect(0, 0, button.getWidth(), button.getHeight());
g.setColor(Color.WHITE);
g.drawString(button.text, 10, 20);
}
}
public class ClickedState implements ButtonState {
@Override
public void render(UIButton button, Graphics2D g) {
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, button.getWidth(), button.getHeight());
g.setColor(Color.WHITE);
g.drawString(button.text, 10, 20);
}
@Override
public void handleLeave(UIButton button, MouseEvent e) {
button.setState(new NormalState());
}
}
public class DisabledState implements ButtonState {
@Override
public void render(UIButton button, Graphics2D g) {
g.setColor(Color.GRAY);
g.fillRect(0, 0, button.getWidth(), button.getHeight());
g.setColor(Color.LIGHT_GRAY);
g.drawString(button.text, 10, 20);
}
@Override
public void setEnabled(UIButton button, boolean enabled) {
if (enabled) {
button.setState(new NormalState());
}
}
}
}
五、优缺点分析
优点
- 单一职责原则:每个状态类负责特定状态的行为
- 开闭原则:新增状态无需修改现有代码
- 消除条件分支:用多态替代复杂的条件语句
- 状态转换明确:状态转换逻辑集中管理
- 提高可维护性:状态逻辑分离,易于理解和维护
- 便于测试:每个状态可以独立测试
- 状态局部化:状态相关行为封装在状态类中
缺点
- 类数量增加:每个状态需要一个类,可能产生大量小类
- 复杂度增加:简单状态机可能过度设计
- 状态共享困难:状态间共享数据较复杂
- 上下文依赖:状态类通常需要了解上下文
- 性能开销:多态调用比条件判断稍慢
- 状态爆炸:状态数量多时难以管理
六、改进与变体
1. 表驱动状态机
java
java
下载
复制
// 使用表驱动的方式实现状态机
public class TableDrivenStateMachine<S, E> {
private S currentState;
private final Map<S, Map<E, Transition<S>>> transitionTable = new HashMap<>();
private final Map<S, Runnable> entryActions = new HashMap<>();
private final Map<S, Runnable> exitActions = new HashMap<>();
private final Map<TransitionKey<S, E>, Runnable> transitionActions = new HashMap<>();
public void addTransition(S from, E event, S to) {
transitionTable.computeIfAbsent(from, k -> new HashMap<>())
.put(event, to);
}
public void addTransition(S from, E event, S to, Runnable action) {
addTransition(from, event, to);
transitionActions.put(new TransitionKey<>(from, event), action);
}
public void onEntry(S state, Runnable action) {
entryActions.put(state, action);
}
public void onExit(S state, Runnable action) {
exitActions.put(state, action);
}
public void fire(E event) {
Map<E, Transition<S>> stateTransitions = transitionTable.get(currentState);
if (stateTransitions == null) {
throw new IllegalStateException("No transitions from state: " + currentState);
}
S toState = stateTransitions.get(event);
if (toState == null) {
throw new IllegalStateException("No transition for event: " + event);
}
// 执行退出动作
Runnable exitAction = exitActions.get(currentState);
if (exitAction != null) {
exitAction.run();
}
// 执行转换动作
Runnable transitionAction = transitionActions.get(new TransitionKey<>(currentState, event));
if (transitionAction != null) {
transitionAction.run();
}
S fromState = currentState;
currentState = toState;
// 执行进入动作
Runnable entryAction = entryActions.get(currentState);
if (entryAction != null) {
entryAction.run();
}
System.out.printf("状态转换: %s --%s--> %s%n", fromState, event, currentState);
}
private static class TransitionKey<S, E> {
private final S from;
private final E event;
public TransitionKey(S from, E event) {
this.from = from;
this.event = event;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TransitionKey<?, ?> that = (TransitionKey<?, ?>) o;
return Objects.equals(from, that.from) && Objects.equals(event, that.event);
}
@Override
public int hashCode() {
return Objects.hash(from, event);
}
}
private static class Transition<S> {
private final S toState;
public Transition(S toState) {
this.toState = toState;
}
public S getToState() {
return toState;
}
}
}
2. 状态模式 + 享元模式
java
java
下载
复制
// 使用享元模式共享状态对象
public class StateFlyweightFactory {
private static final Map<String, OrderState> statePool = new ConcurrentHashMap<>();
static {
// 预加载所有状态
statePool.put("NEW", new NewOrderState());
statePool.put("PAID", new PaidState());
statePool.put("SHIPPED", new ShippedState());
statePool.put("COMPLETED", new CompletedState());
statePool.put("CANCELED", new CanceledState());
}
public static OrderState getState(String stateKey) {
OrderState state = statePool.get(stateKey);
if (state == null) {
throw new IllegalArgumentException("未知状态: " + stateKey);
}
return state;
}
public static void registerState(String stateKey, OrderState state) {
statePool.put(stateKey, state);
}
}
// 修改后的上下文
public class FlyweightOrderContext {
private OrderState currentState;
private String orderId;
public FlyweightOrderContext(String orderId, String initialState) {
this.orderId = orderId;
this.currentState = StateFlyweightFactory.getState(initialState);
}
public void transitionTo(String newStateKey) {
OrderState newState = StateFlyweightFactory.getState(newStateKey);
System.out.printf("订单 %s: %s -> %s%n",
orderId, currentState.getStatusName(), newState.getStatusName());
this.currentState = newState;
}
}
3. 状态模式 + 策略模式
java
java
下载
复制
// 结合策略模式,状态可以动态替换策略
public interface ProcessingStrategy {
void process(Order order);
boolean canExecute(Order order);
String getStrategyName();
}
public class StateDrivenProcessor {
private OrderState currentState;
private ProcessingStrategy currentStrategy;
private Map<Class<? extends OrderState>, ProcessingStrategy> strategyMap = new HashMap<>();
public StateDrivenProcessor() {
// 初始化状态-策略映射
strategyMap.put(NewOrderState.class, new ValidationStrategy());
strategyMap.put(PaidState.class, new PaymentVerificationStrategy());
strategyMap.put(ShippedState.class, new ShippingStrategy());
strategyMap.put(CompletedState.class, new CompletionStrategy());
// 初始状态
setState(new NewOrderState());
}
public void setState(OrderState state) {
this.currentState = state;
this.currentStrategy = strategyMap.get(state.getClass());
if (currentStrategy == null) {
throw new IllegalArgumentException("没有找到对应的处理策略: " + state.getClass());
}
}
public void processOrder(Order order) {
if (currentStrategy.canExecute(order)) {
currentStrategy.process(order);
} else {
System.out.println("当前状态不支持此处理策略");
}
}
}
4. 可配置状态机
java
java
下载
复制
// 从配置文件加载状态机定义
public class ConfigurableStateMachine {
private String currentState;
private final Map<String, StateDefinition> stateDefinitions = new HashMap<>();
private final ObjectMapper objectMapper = new ObjectMapper();
public static class StateDefinition {
private String name;
private Map<String, String> transitions = new HashMap<>();
private List<String> entryActions = new ArrayList<>();
private List<String> exitActions = new ArrayList<>();
private Map<String, String> conditions = new HashMap<>();
// getters and setters
}
public void loadFromJson(String jsonConfig) throws IOException {
StateDefinition[] states = objectMapper.readValue(jsonConfig, StateDefinition[].class);
for (StateDefinition state : states) {
stateDefinitions.put(state.getName(), state);
}
// 设置初始状态
if (!stateDefinitions.isEmpty()) {
currentState = states[0].getName();
}
}
public boolean fire(String event, Map<String, Object> context) {
StateDefinition currentStateDef = stateDefinitions.get(currentState);
if (currentStateDef == null) {
return false;
}
String nextState = currentStateDef.getTransitions().get(event);
if (nextState == null) {
return false;
}
// 检查条件
String condition = currentStateDef.getConditions().get(event);
if (condition != null && !evaluateCondition(condition, context)) {
return false;
}
// 执行退出动作
executeActions(currentStateDef.getExitActions(), context);
// 状态转换
String oldState = currentState;
currentState = nextState;
// 执行进入动作
StateDefinition newStateDef = stateDefinitions.get(currentState);
executeActions(newStateDef.getEntryActions(), context);
System.out.printf("状态转换: %s --%s--> %s%n", oldState, event, currentState);
return true;
}
private boolean evaluateCondition(String condition, Map<String, Object> context) {
// 简单的条件表达式求值
// 实际实现可以使用表达式引擎如MVEL、SpEL等
return true; // 简化实现
}
private void executeActions(List<String> actions, Map<String, Object> context) {
for (String action : actions) {
System.out.println("执行动作: " + action);
// 实际执行动作逻辑
}
}
}
七、注意事项
1. 状态对象管理
java
java
下载
复制
// 状态对象生命周期管理
public class StateLifecycleManager {
private Map<Class<? extends State>, State> stateInstances = new HashMap<>();
private boolean useSingletonStates = true;
public State getState(Class<? extends State> stateClass) {
if (useSingletonStates) {
// 使用单例状态对象
return stateInstances.computeIfAbsent(stateClass, this::createState);
} else {
// 每次都创建新实例
return createState(stateClass);
}
}
private State createState(Class<? extends State> stateClass) {
try {
return stateClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("创建状态实例失败: " + stateClass.getName(), e);
}
}
public void cleanup() {
// 清理状态对象
for (State state : stateInstances.values()) {
if (state instanceof Disposable) {
((Disposable) state).dispose();
}
}
stateInstances.clear();
}
public interface Disposable {
void dispose();
}
}
2. 线程安全实现
java
java
下载
复制
// 线程安全的状态上下文
public class ThreadSafeStateContext<S extends State> {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private S currentState;
private final StateValidator<S> validator;
private final List<StateChangeListener<S>> listeners = new CopyOnWriteArrayList<>();
public ThreadSafeStateContext(S initialState, StateValidator<S> validator) {
this.currentState = initialState;
this.validator = validator;
}
public void transitionTo(S newState, Object... args) {
lock.writeLock().lock();
try {
// 验证状态转换
if (!validator.isValidTransition(currentState, newState, args)) {
throw new IllegalStateException(
String.format("无效的状态转换: %s -> %s",
currentState.getClass().getSimpleName(),
newState.getClass().getSimpleName()));
}
S oldState = currentState;
// 执行退出动作
oldState.onExit(this, args);
// 状态转换
currentState = newState;
// 执行进入动作
newState.onEnter(this, args);
// 通知监听器
notifyStateChange(oldState, newState, args);
} finally {
lock.writeLock().unlock();
}
}
public void handleEvent(Event event) {
lock.readLock().lock();
try {
currentState.handleEvent(this, event);
} finally {
lock.readLock().unlock();
}
}
public S getCurrentState() {
lock.readLock().lock();
try {
return currentState;
} finally {
lock.readLock().unlock();
}
}
private void notifyStateChange(S oldState, S newState, Object... args) {
for (StateChangeListener<S> listener : listeners) {
listener.onStateChanged(oldState, newState, args);
}
}
public void addStateChangeListener(StateChangeListener<S> listener) {
listeners.add(listener);
}
public interface StateValidator<S> {
boolean isValidTransition(S fromState, S toState, Object... args);
}
public interface StateChangeListener<S> {
void onStateChanged(S oldState, S newState, Object... args);
}
}
3. 状态持久化
java
java
下载
复制
// 状态持久化支持
public class PersistentStateContext<S extends Serializable> {
private S currentState;
private final StatePersistence<S> persistence;
private final String contextId;
public PersistentStateContext(String contextId, S initialState,
StatePersistence<S> persistence) {
this.contextId = contextId;
this.persistence = persistence;
// 尝试从持久化存储加载状态
S savedState = persistence.loadState(contextId);
this.currentState = (savedState != null) ? savedState : initialState;
}
public synchronized void transitionTo(S newState, boolean persist) {
S oldState = currentState;
currentState = newState;
if (persist) {
persistence.saveState(contextId, newState);
}
// 记录状态转换日志
persistence.logTransition(contextId, oldState, newState);
}
public S getCurrentState() {
return currentState;
}
public List<StateTransition<S>> getTransitionHistory() {
return persistence.getTransitionHistory(contextId);
}
public interface StatePersistence<S> {
void saveState(String contextId, S state);
S loadState(String contextId);
void logTransition(String contextId, S fromState, S toState);
List<StateTransition<S>> getTransitionHistory(String contextId);
}
public static class StateTransition<S> {
private final S fromState;
private final S toState;
private final Date timestamp;
public StateTransition(S fromState, S toState) {
this.fromState = fromState;
this.toState = toState;
this.timestamp = new Date();
}
}
}
4. 状态模式与枚举结合
java
java
下载
复制
// 使用枚举实现简单状态机
public enum OrderStatus {
NEW {
@Override
public boolean canTransitionTo(OrderStatus next) {
return next == PAID || next == CANCELLED;
}
@Override
public void onEnter(Order order) {
order.setCreatedTime(new Date());
System.out.println("新订单创建");
}
},
PAID {
@Override
public boolean canTransitionTo(OrderStatus next) {
return next == SHIPPED || next == CANCELLED;
}
@Override
public void onEnter(Order order) {
order.setPaidTime(new Date());
System.out.println("订单已支付");
}
},
SHIPPED {
@Override
public boolean canTransitionTo(OrderStatus next) {
return next == DELIVERED || next == CANCELLED;
}
@Override
public void onEnter(Order order) {
order.setShippedTime(new Date());
System.out.println("订单已发货");
}
},
DELIVERED {
@Override
public boolean canTransitionTo(OrderStatus next) {
return next == COMPLETED;
}
@Override
public void onEnter(Order order) {
order.setDeliveredTime(new Date());
System.out.println("订单已送达");
}
},
COMPLETED {
@Override
public boolean canTransitionTo(OrderStatus next) {
return false; // 最终状态
}
},
CANCELLED {
@Override
public boolean canTransitionTo(OrderStatus next) {
return false; // 最终状态
}
@Override
public void onEnter(Order order) {
order.setCancelledTime(new Date());
System.out.println("订单已取消");
}
};
public abstract boolean canTransitionTo(OrderStatus next);
public void onEnter(Order order) {
// 默认空实现
}
public void onExit(Order order) {
// 默认空实现
}
// 状态转换方法
public OrderStatus transitionTo(OrderStatus next, Order order) {
if (!canTransitionTo(next)) {
throw new IllegalStateException(
String.format("不能从状态 %s 转换到 %s", this, next));
}
this.onExit(order);
OrderStatus oldStatus = order.getStatus();
order.setStatus(next);
next.onEnter(order);
return oldStatus;
}
}
八、与其他模式的关系
1. 状态模式 vs 策略模式
java
java
下载
复制
// 状态模式:行为随状态改变,状态知道其他状态的存在
// 策略模式:算法可互换,策略之间相互独立
// 状态模式示例
public class StatePatternDemo {
public static void main(String[] args) {
OrderContext order = new OrderContext("ORD001");
order.pay(); // 状态自动转换
order.ship(); // 状态自动转换
}
}
// 策略模式示例
public class StrategyPatternDemo {
public static void main(String[] args) {
PaymentProcessor processor = new PaymentProcessor();
processor.setStrategy(new CreditCardStrategy());
processor.process(100.0); // 使用信用卡
processor.setStrategy(new PayPalStrategy());
processor.process(200.0); // 使用PayPal
}
}
2. 状态模式 + 观察者模式
java
java
下载
复制
// 状态变化通知观察者
public class ObservableStateContext {
private State currentState;
private List<StateObserver> observers = new ArrayList<>();
public void setState(State newState) {
State oldState = this.currentState;
this.currentState = newState;
// 通知观察者
for (StateObserver observer : observers) {
observer.onStateChanged(oldState, newState);
}
}
public void addObserver(StateObserver observer) {
observers.add(observer);
}
public interface StateObserver {
void onStateChanged(State oldState, State newState);
}
}
3. 状态模式 + 访问者模式
java
java
下载
复制
// 访问者处理不同状态
public interface StateVisitor {
void visit(NewOrderState state);
void visit(PaidState state);
void visit(ShippedState state);
void visit(CompletedState state);
void visit(CanceledState state);
}
public abstract class OrderState {
public abstract void accept(StateVisitor visitor);
// 其他方法...
}
public class NewOrderState extends OrderState {
@Override
public void accept(StateVisitor visitor) {
visitor.visit(this);
}
}
// 具体访问者
public class StateStatisticsVisitor implements StateVisitor {
private Map<Class<? extends OrderState>, Integer> statistics = new HashMap<>();
@Override
public void visit(NewOrderState state) {
statistics.merge(NewOrderState.class, 1, Integer::sum);
}
@Override
public void visit(PaidState state) {
statistics.merge(PaidState.class, 1, Integer::sum);
}
// 实现其他visit方法...
public Map<Class<? extends OrderState>, Integer> getStatistics() {
return new HashMap<>(statistics);
}
}
九、实际应用建议
适用场景判断
适合使用状态模式的场景:
- 对象的行为依赖于它的状态,并且必须在运行时根据状态改变行为
- 操作中有大量条件语句,且这些条件依赖于对象的状态
- 状态转换逻辑复杂,需要清晰的管理
- 状态数量较多,且可能频繁增加
- 需要实现状态机或工作流引擎
不适合的场景:
- 状态数量很少(2-3个)且稳定
- 状态转换逻辑简单,用条件判断足够清晰
- 对性能要求极高,需要避免多态调用开销
- 状态之间没有明显的行为差异
最佳实践
- 明确状态转换:在状态类中定义转换逻辑
- 使用享元模式:共享无状态的状态对象
- 考虑线程安全:多线程环境需要同步
- 添加状态验证:验证状态转换的合法性
- 提供状态历史:记录状态转换轨迹
- 实现状态持久化:支持状态恢复
- 使用生成器模式:简化状态机构建
- 添加监控和日志:便于调试和监控
性能优化策略
java
java
下载
复制
// 状态机优化
public class OptimizedStateMachine {
// 1. 使用枚举代替类
public enum OptimizedState {
STATE_A, STATE_B, STATE_C;
private static final Map<OptimizedState, Map<String, OptimizedState>> transitions =
new EnumMap<>(OptimizedState.class);
static {
// 初始化状态转换表
transitions.put(STATE_A, Map.of("event1", STATE_B, "event2", STATE_C));
transitions.put(STATE_B, Map.of("event3", STATE_C));
transitions.put(STATE_C, Collections.emptyMap());
}
public OptimizedState transition(String event) {
Map<String, OptimizedState> stateTransitions = transitions.get(this);
if (stateTransitions != null) {
OptimizedState nextState = stateTransitions.get(event);
if (nextState != null) {
return nextState;
}
}
throw new IllegalStateException("无效的事件: " + event + " 对于状态: " + this);
}
}
// 2. 使用数组提高性能
public class ArrayBasedStateMachine {
private int currentState;
private final int[][] transitionTable;
private final Runnable[][] actionTable;
public ArrayBasedStateMachine(int stateCount, int eventCount) {
transitionTable = new int[stateCount][eventCount];
actionTable = new Runnable[stateCount][eventCount];
// 初始化所有转换为无效状态(-1)
for (int i = 0; i < stateCount; i++) {
Arrays.fill(transitionTable[i], -1);
}
}
public void addTransition(int fromState, int event, int toState, Runnable action) {
transitionTable[fromState][event] = toState;
actionTable[fromState][event] = action;
}
public boolean fire(int event) {
int nextState = transitionTable[currentState][event];
if (nextState == -1) {
return false;
}
Runnable action = actionTable[currentState][event];
if (action != null) {
action.run();
}
currentState = nextState;
return true;
}
}
}
十、总结
状态模式是处理对象状态驱动行为的强大工具,特别适合状态转换复杂、行为随状态变化的系统。正确使用时,它能显著提高代码的可维护性和扩展性。
关键要点:
- 将每种状态封装为独立的类
- 状态转换逻辑可以在上下文或状态类中
- 使用多态替代复杂的条件判断
- 考虑状态对象的创建和管理策略
- 为复杂状态机提供配置和持久化支持
实现建议:
- 简单状态机可使用枚举实现
- 复杂状态机考虑表驱动或DSL配置
- 多线程环境需确保线程安全
- 性能敏感场景可优化状态查找
- 生产环境应添加状态监控和日志
状态模式与策略模式结构相似但意图不同:策略模式关注算法的可互换性,而状态模式关注行为随状态的变化。在复杂系统中,状态模式常与其他模式(如观察者、访问者、享元模式)结合使用,以构建更灵活的状态管理系统。