深入解析:设计模式-状态模式详解

news/2025/9/25 15:23:21/文章来源:https://www.cnblogs.com/lxjshuju/p/19111285

状态模式详解

目录

  1. 状态模式简介
  2. 核心流程
  3. 重难点分析
  4. Spring中的源码分析
  5. 具体使用场景
  6. 面试高频点
  7. 使用总结

状态模式简介

定义

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。状态模式将状态封装成独立的类,并将动作委托到代表当前状态的对象。

核心思想

  • 状态封装:将每个状态封装成独立的类
  • 行为委托:将行为委托给当前状态对象
  • 状态转换:通过状态对象管理状态转换
  • 消除条件判断:用多态替代大量的条件判断

模式结构


核心流程

状态模式流程图

基本实现流程

1. 定义抽象状态类
// 抽象状态类
public abstract class State
{
protected Context context;
public void setContext(Context context) {
this.context = context;
}
public abstract void handleRequest1();
public abstract void handleRequest2();
public abstract void handleRequest3();
// 状态转换方法
protected void changeState(State newState) {
context.changeState(newState);
}
}
2. 定义环境类
// 环境类
public class Context
{
private State currentState;
public Context() {
// 设置初始状态
this.currentState = new ConcreteStateA();
this.currentState.setContext(this);
}
public void changeState(State newState) {
this.currentState = newState;
this.currentState.setContext(this);
System.out.println("状态转换到: " + newState.getClass().getSimpleName());
}
public void request1() {
currentState.handleRequest1();
}
public void request2() {
currentState.handleRequest2();
}
public void request3() {
currentState.handleRequest3();
}
public State getCurrentState() {
return currentState;
}
}
3. 实现具体状态类
// 具体状态A
public class ConcreteStateA
extends State {
@Override
public void handleRequest1() {
System.out.println("状态A处理请求1");
// 状态A处理请求1的逻辑
}
@Override
public void handleRequest2() {
System.out.println("状态A处理请求2,转换到状态B");
changeState(new ConcreteStateB());
}
@Override
public void handleRequest3() {
System.out.println("状态A处理请求3,转换到状态C");
changeState(new ConcreteStateC());
}
}
// 具体状态B
public class ConcreteStateB
extends State {
@Override
public void handleRequest1() {
System.out.println("状态B处理请求1,转换到状态A");
changeState(new ConcreteStateA());
}
@Override
public void handleRequest2() {
System.out.println("状态B处理请求2");
// 状态B处理请求2的逻辑
}
@Override
public void handleRequest3() {
System.out.println("状态B处理请求3,转换到状态C");
changeState(new ConcreteStateC());
}
}
// 具体状态C
public class ConcreteStateC
extends State {
@Override
public void handleRequest1() {
System.out.println("状态C处理请求1,转换到状态A");
changeState(new ConcreteStateA());
}
@Override
public void handleRequest2() {
System.out.println("状态C处理请求2,转换到状态B");
changeState(new ConcreteStateB());
}
@Override
public void handleRequest3() {
System.out.println("状态C处理请求3");
// 状态C处理请求3的逻辑
}
}
4. 客户端使用
public class Client
{
public static void main(String[] args) {
Context context = new Context();
// 初始状态是A
System.out.println("当前状态: " + context.getCurrentState().getClass().getSimpleName());
// 测试状态转换
context.request1();
// 状态A处理请求1
context.request2();
// 状态A -> 状态B
context.request2();
// 状态B处理请求2
context.request3();
// 状态B -> 状态C
context.request3();
// 状态C处理请求3
context.request1();
// 状态C -> 状态A
}
}

重难点分析

重难点1:状态转换的复杂性

问题描述

当状态转换逻辑复杂时,如何管理状态之间的转换关系。

解决方案
// 状态转换表
public class StateTransitionTable
{
private final Map<
State, Map<
String, State>
> transitions = new HashMap<
>();
public void addTransition(State from, String event, State to) {
transitions.computeIfAbsent(from, k ->
new HashMap<
>()).put(event, to);
}
public State getNextState(State currentState, String event) {
Map<
String, State> stateTransitions = transitions.get(currentState);
if (stateTransitions != null) {
return stateTransitions.get(event);
}
return null;
}
}
// 使用状态转换表的状态机
public class StateMachine
{
private State currentState;
private final StateTransitionTable transitionTable;
public StateMachine(State initialState, StateTransitionTable transitionTable) {
this.currentState = initialState;
this.transitionTable = transitionTable;
this.currentState.setContext(this);
}
public void handleEvent(String event) {
State nextState = transitionTable.getNextState(currentState, event);
if (nextState != null) {
changeState(nextState);
} else {
System.out.println("无效的状态转换: " + currentState.getClass().getSimpleName() + " -> " + event);
}
}
private void changeState(State newState) {
this.currentState = newState;
this.currentState.setContext(this);
System.out.println("状态转换到: " + newState.getClass().getSimpleName());
}
}
// 状态转换规则
public class StateTransitionRules
{
public static StateTransitionTable createOrderStateTransitionTable() {
StateTransitionTable table = new StateTransitionTable();
// 订单状态转换规则
OrderState pending = new OrderState("PENDING");
OrderState confirmed = new OrderState("CONFIRMED");
OrderState shipped = new OrderState("SHIPPED");
OrderState delivered = new OrderState("DELIVERED");
OrderState cancelled = new OrderState("CANCELLED");
// 添加转换规则
table.addTransition(pending, "CONFIRM", confirmed);
table.addTransition(pending, "CANCEL", cancelled);
table.addTransition(confirmed, "SHIP", shipped);
table.addTransition(confirmed, "CANCEL", cancelled);
table.addTransition(shipped, "DELIVER", delivered);
return table;
}
}

重难点2:状态的历史记录

问题描述

如何记录状态转换的历史,支持状态回滚和重放。

解决方案
// 状态历史记录
public class StateHistory
{
private final List<
StateRecord> history = new ArrayList<
>();
private int currentIndex = -1;
public void addState(State state, String event) {
// 移除当前位置之后的所有记录
if (currentIndex < history.size() - 1) {
history.subList(currentIndex + 1, history.size()).clear();
}
StateRecord record = new StateRecord(state, event, System.currentTimeMillis());
history.add(record);
currentIndex = history.size() - 1;
}
public StateRecord getCurrentState() {
if (currentIndex >= 0 && currentIndex < history.size()) {
return history.get(currentIndex);
}
return null;
}
public StateRecord getPreviousState() {
if (currentIndex >
0) {
currentIndex--;
return history.get(currentIndex);
}
return null;
}
public StateRecord getNextState() {
if (currentIndex < history.size() - 1) {
currentIndex++;
return history.get(currentIndex);
}
return null;
}
public List<
StateRecord> getHistory() {
return new ArrayList<
>(history);
}
}
// 状态记录
public class StateRecord
{
private final State state;
private final String event;
private final long timestamp;
public StateRecord(State state, String event, long timestamp) {
this.state = state;
this.event = event;
this.timestamp = timestamp;
}
// getter方法
public State getState() {
return state;
}
public String getEvent() {
return event;
}
public long getTimestamp() {
return timestamp;
}
}
// 支持历史记录的状态机
public class HistoricalStateMachine
extends StateMachine {
private final StateHistory history;
public HistoricalStateMachine(State initialState, StateTransitionTable transitionTable) {
super(initialState, transitionTable);
this.history = new StateHistory();
this.history.addState(initialState, "INITIAL");
}
@Override
public void handleEvent(String event) {
State nextState = transitionTable.getNextState(currentState, event);
if (nextState != null) {
history.addState(nextState, event);
changeState(nextState);
} else {
System.out.println("无效的状态转换: " + currentState.getClass().getSimpleName() + " -> " + event);
}
}
public void rollback() {
StateRecord previousState = history.getPreviousState();
if (previousState != null) {
changeState(previousState.getState());
}
}
public void replay() {
StateRecord nextState = history.getNextState();
if (nextState != null) {
changeState(nextState.getState());
}
}
}

重难点3:状态的并发安全

问题描述

在多线程环境下,如何确保状态转换的线程安全。

解决方案
// 线程安全的状态机
public class ThreadSafeStateMachine
{
private volatile State currentState;
private final Object stateLock = new Object();
private final StateTransitionTable transitionTable;
public ThreadSafeStateMachine(State initialState, StateTransitionTable transitionTable) {
this.currentState = initialState;
this.transitionTable = transitionTable;
this.currentState.setContext(this);
}
public void handleEvent(String event) {
synchronized (stateLock) {
State nextState = transitionTable.getNextState(currentState, event);
if (nextState != null) {
changeState(nextState);
} else {
System.out.println("无效的状态转换: " + currentState.getClass().getSimpleName() + " -> " + event);
}
}
}
private void changeState(State newState) {
this.currentState = newState;
this.currentState.setContext(this);
System.out.println("状态转换到: " + newState.getClass().getSimpleName());
}
public State getCurrentState() {
return currentState;
}
}
// 使用原子操作的状态机
public class AtomicStateMachine
{
private final AtomicReference<
State> currentState;
private final StateTransitionTable transitionTable;
public AtomicStateMachine(State initialState, StateTransitionTable transitionTable) {
this.currentState = new AtomicReference<
>(initialState);
this.transitionTable = transitionTable;
this.currentState.get().setContext(this);
}
public void handleEvent(String event) {
State current = currentState.get();
State nextState = transitionTable.getNextState(current, event);
if (nextState != null) {
if (currentState.compareAndSet(current, nextState)) {
nextState.setContext(this);
System.out.println("状态转换到: " + nextState.getClass().getSimpleName());
} else {
// 状态已被其他线程修改,重试
handleEvent(event);
}
} else {
System.out.println("无效的状态转换: " + current.getClass().getSimpleName() + " -> " + event);
}
}
public State getCurrentState() {
return currentState.get();
}
}

重难点4:状态的持久化

问题描述

如何将状态信息持久化到数据库或文件中,支持系统重启后的状态恢复。

解决方案
// 状态持久化接口
public interface StatePersistence {
void saveState(String contextId, State state);
State loadState(String contextId);
void saveStateHistory(String contextId, List<
StateRecord> history);
List<
StateRecord> loadStateHistory(String contextId);
}
// 数据库状态持久化
public class DatabaseStatePersistence
implements StatePersistence {
private final JdbcTemplate jdbcTemplate;
public DatabaseStatePersistence(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void saveState(String contextId, State state) {
String sql = "INSERT INTO state_context (context_id, state_class, state_data, created_at) VALUES (?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE state_class = ?, state_data = ?, updated_at = ?";
jdbcTemplate.update(sql, contextId, state.getClass().getName(),
serializeState(state), new Date(),
state.getClass().getName(), serializeState(state), new Date());
}
@Override
public State loadState(String contextId) {
String sql = "SELECT state_class, state_data FROM state_context WHERE context_id = ?";
try {
return jdbcTemplate.queryForObject(sql, (rs, rowNum) ->
{
String stateClass = rs.getString("state_class");
String stateData = rs.getString("state_data");
return deserializeState(stateClass, stateData);
}, contextId);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
private String serializeState(State state) {
// 序列化状态对象
return JSON.toJSONString(state);
}
private State deserializeState(String stateClass, String stateData) {
// 反序列化状态对象
try {
Class<
?> clazz = Class.forName(stateClass);
return (State) JSON.parseObject(stateData, clazz);
} catch (ClassNotFoundException e) {
throw new RuntimeException("无法加载状态类: " + stateClass, e);
}
}
}
// 支持持久化的状态机
public class PersistentStateMachine
extends StateMachine {
private final StatePersistence persistence;
private final String contextId;
public PersistentStateMachine(String contextId, State initialState,
StateTransitionTable transitionTable,
StatePersistence persistence) {
super(initialState, transitionTable);
this.contextId = contextId;
this.persistence = persistence;
// 尝试从持久化存储中恢复状态
State savedState = persistence.loadState(contextId);
if (savedState != null) {
this.currentState = savedState;
this.currentState.setContext(this);
}
}
@Override
public void handleEvent(String event) {
super.handleEvent(event);
// 保存状态到持久化存储
persistence.saveState(contextId, currentState);
}
}

Spring中的源码分析

Spring的状态机实现

// Spring StateMachine接口
public interface StateMachine<
S, E> extends StateMachineAccessor<
S, E> {
void start();
void stop();
boolean sendEvent(E event);
boolean sendEvent(Message<
E> event);
void setStateMachineErrorHandler(StateMachineErrorHandler errorHandler);
void addStateListener(StateMachineListener<
S, E> listener);
void removeStateListener(StateMachineListener<
S, E> listener);
}
// Spring StateMachineConfigurer接口
public interface StateMachineConfigurer<
S, E> {
void configure(StateMachineStateConfigurer<
S, E> states) throws Exception;
void configure(StateMachineTransitionConfigurer<
S, E> transitions) throws Exception;
void configure(StateMachineConfigurationConfigurer<
S, E> config) throws Exception;
}
// Spring StateMachineBuilder
public class StateMachineBuilder
<
S, E> {
public static <
S, E> StateMachineBuilder<
S, E> builder() {
return new StateMachineBuilder<
>();
}
public StateMachine<
S, E> build() {
return new DefaultStateMachine<
>(stateMachineModel, stateMachineAccessor);
}
public StateMachineBuilder<
S, E> configure(StateMachineConfigurer<
S, E> configurer) {
try {
configurer.configure(states);
configurer.configure(transitions);
configurer.configure(config);
} catch (Exception e) {
throw new StateMachineException("Error configuring state machine", e);
}
return this;
}
}

Spring的状态配置

// 状态配置
@Configuration
@EnableStateMachine
public class StateMachineConfig
extends StateMachineConfigurerAdapter<
String, String> {
@Override
public void configure(StateMachineStateConfigurer<
String, String> states) throws Exception {
states
.withStates()
.initial("SI")
.state("S1")
.state("S2")
.end("SF");
}
@Override
public void configure(StateMachineTransitionConfigurer<
String, String> transitions) throws Exception {
transitions
.withExternal()
.source("SI").target("S1").event("E1")
.and()
.withExternal()
.source("S1").target("S2").event("E2")
.and()
.withExternal()
.source("S2").target("SF").event("E3");
}
}
// 状态机监听器
@Component
public class StateMachineListener
implements StateMachineListener<
String, String> {
@Override
public void stateChanged(State<
String, String> from, State<
String, String> to) {
System.out.println("状态转换: " + from.getId() + " -> " + to.getId());
}
@Override
public void stateEntered(State<
String, String> state) {
System.out.println("进入状态: " + state.getId());
}
@Override
public void stateExited(State<
String, String> state) {
System.out.println("退出状态: " + state.getId());
}
}

Spring的状态机使用

// 状态机服务
@Service
public class StateMachineService
{
@Autowired
private StateMachine<
String, String> stateMachine;
public void startStateMachine() {
stateMachine.start();
}
public void stopStateMachine() {
stateMachine.stop();
}
public boolean sendEvent(String event) {
return stateMachine.sendEvent(event);
}
public String getCurrentState() {
return stateMachine.getState().getId();
}
}
// 状态机控制器
@RestController
@RequestMapping("/statemachine")
public class StateMachineController
{
@Autowired
private StateMachineService stateMachineService;
@PostMapping("/start")
public ResponseEntity<
String> start() {
stateMachineService.startStateMachine();
return ResponseEntity.ok("状态机已启动");
}
@PostMapping("/stop")
public ResponseEntity<
String> stop() {
stateMachineService.stopStateMachine();
return ResponseEntity.ok("状态机已停止");
}
@PostMapping("/event")
public ResponseEntity<
String> sendEvent(@RequestParam String event) {
boolean result = stateMachineService.sendEvent(event);
if (result) {
return ResponseEntity.ok("事件发送成功,当前状态: " + stateMachineService.getCurrentState());
} else {
return ResponseEntity.badRequest().body("事件发送失败");
}
}
}

具体使用场景

1. 订单状态管理

// 订单状态枚举
public enum OrderStatus {
PENDING("待处理"),
CONFIRMED("已确认"),
SHIPPED("已发货"),
DELIVERED("已送达"),
CANCELLED("已取消");
private final String description;
OrderStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 订单状态机
public class OrderStateMachine
{
private OrderStatus currentStatus;
private final Order order;
public OrderStateMachine(Order order) {
this.order = order;
this.currentStatus = OrderStatus.PENDING;
}
public boolean confirm() {
if (currentStatus == OrderStatus.PENDING) {
currentStatus = OrderStatus.CONFIRMED;
order.setStatus(currentStatus);
order.setConfirmedAt(new Date());
return true;
}
return false;
}
public boolean ship() {
if (currentStatus == OrderStatus.CONFIRMED) {
currentStatus = OrderStatus.SHIPPED;
order.setStatus(currentStatus);
order.setShippedAt(new Date());
return true;
}
return false;
}
public boolean deliver() {
if (currentStatus == OrderStatus.SHIPPED) {
currentStatus = OrderStatus.DELIVERED;
order.setStatus(currentStatus);
order.setDeliveredAt(new Date());
return true;
}
return false;
}
public boolean cancel() {
if (currentStatus == OrderStatus.PENDING || currentStatus == OrderStatus.CONFIRMED) {
currentStatus = OrderStatus.CANCELLED;
order.setStatus(currentStatus);
order.setCancelledAt(new Date());
return true;
}
return false;
}
public OrderStatus getCurrentStatus() {
return currentStatus;
}
}
// 订单类
public class Order
{
private String id;
private String customerId;
private List<
OrderItem> items;
private OrderStatus status;
private Date createdAt;
private Date confirmedAt;
private Date shippedAt;
private Date deliveredAt;
private Date cancelledAt;
// 构造函数、getter和setter方法
public Order(String id, String customerId, List<
OrderItem> items) {
this.id = id;
this.customerId = customerId;
this.items = items;
this.status = OrderStatus.PENDING;
this.createdAt = new Date();
}
// getter和setter方法
public String getId() {
return id;
}
public String getCustomerId() {
return customerId;
}
public List<
OrderItem> getItems() {
return items;
}
public OrderStatus getStatus() {
return status;
}
public void setStatus(OrderStatus status) {
this.status = status;
}
public Date getCreatedAt() {
return createdAt;
}
public Date getConfirmedAt() {
return confirmedAt;
}
public void setConfirmedAt(Date confirmedAt) {
this.confirmedAt = confirmedAt;
}
public Date getShippedAt() {
return shippedAt;
}
public void setShippedAt(Date shippedAt) {
this.shippedAt = shippedAt;
}
public Date getDeliveredAt() {
return deliveredAt;
}
public void setDeliveredAt(Date deliveredAt) {
this.deliveredAt = deliveredAt;
}
public Date getCancelledAt() {
return cancelledAt;
}
public void setCancelledAt(Date cancelledAt) {
this.cancelledAt = cancelledAt;
}
}

2. 游戏角色状态

// 游戏角色状态接口
public interface CharacterState {
void move(Character character);
void attack(Character character);
void defend(Character character);
void useSkill(Character character, String skill);
}
// 正常状态
public class NormalState
implements CharacterState {
@Override
public void move(Character character) {
System.out.println(character.getName() + " 正常移动");
character.setPosition(character.getPosition() + 1);
}
@Override
public void attack(Character character) {
System.out.println(character.getName() + " 发起攻击");
character.setHealth(character.getHealth() - 10);
}
@Override
public void defend(Character character) {
System.out.println(character.getName() + " 进入防御状态");
character.setState(new DefendingState());
}
@Override
public void useSkill(Character character, String skill) {
System.out.println(character.getName() + " 使用技能: " + skill);
character.setMana(character.getMana() - 20);
}
}
// 防御状态
public class DefendingState
implements CharacterState {
@Override
public void move(Character character) {
System.out.println(character.getName() + " 防御状态下移动缓慢");
character.setPosition(character.getPosition() + 0.5);
}
@Override
public void attack(Character character) {
System.out.println(character.getName() + " 防御状态下无法攻击");
}
@Override
public void defend(Character character) {
System.out.println(character.getName() + " 继续防御");
}
@Override
public void useSkill(Character character, String skill) {
System.out.println(character.getName() + " 防御状态下无法使用技能");
}
}
// 游戏角色类
public class Character
{
private String name;
private int health;
private int mana;
private double position;
private CharacterState state;
public Character(String name) {
this.name = name;
this.health = 100;
this.mana = 100;
this.position = 0;
this.state = new NormalState();
}
public void move() {
state.move(this);
}
public void attack() {
state.attack(this);
}
public void defend() {
state.defend(this);
}
public void useSkill(String skill) {
state.useSkill(this, skill);
}
// getter和setter方法
public String getName() {
return name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getMana() {
return mana;
}
public void setMana(int mana) {
this.mana = mana;
}
public double getPosition() {
return position;
}
public void setPosition(double position) {
this.position = position;
}
public CharacterState getState() {
return state;
}
public void setState(CharacterState state) {
this.state = state;
}
}

3. 工作流状态管理

// 工作流状态接口
public interface WorkflowState {
void process(WorkflowContext context);
boolean canTransitionTo(WorkflowState nextState);
}
// 待审批状态
public class PendingApprovalState
implements WorkflowState {
@Override
public void process(WorkflowContext context) {
System.out.println("工作流处于待审批状态");
// 发送审批通知
sendApprovalNotification(context);
}
@Override
public boolean canTransitionTo(WorkflowState nextState) {
return nextState instanceof ApprovedState || nextState instanceof RejectedState;
}
private void sendApprovalNotification(WorkflowContext context) {
System.out.println("发送审批通知给: " + context.getApprover());
}
}
// 已审批状态
public class ApprovedState
implements WorkflowState {
@Override
public void process(WorkflowContext context) {
System.out.println("工作流已审批通过");
// 执行后续流程
executeNextStep(context);
}
@Override
public boolean canTransitionTo(WorkflowState nextState) {
return nextState instanceof InProgressState || nextState instanceof CompletedState;
}
private void executeNextStep(WorkflowContext context) {
System.out.println("执行下一步: " + context.getNextStep());
}
}
// 工作流上下文
public class WorkflowContext
{
private String workflowId;
private String currentStep;
private String nextStep;
private String approver;
private Map<
String, Object> data;
public WorkflowContext(String workflowId) {
this.workflowId = workflowId;
this.data = new HashMap<
>();
}
// getter和setter方法
public String getWorkflowId() {
return workflowId;
}
public String getCurrentStep() {
return currentStep;
}
public void setCurrentStep(String currentStep) {
this.currentStep = currentStep;
}
public String getNextStep() {
return nextStep;
}
public void setNextStep(String nextStep) {
this.nextStep = nextStep;
}
public String getApprover() {
return approver;
}
public void setApprover(String approver) {
this.approver = approver;
}
public Map<
String, Object> getData() {
return data;
}
public void setData(Map<
String, Object> data) {
this.data = data;
}
}

面试高频点

面试知识点思维导图

1. 状态模式的基本概念

问题:什么是状态模式?

答案要点:

问题:状态模式有哪些角色?

答案要点:

  • Context(环境类):定义客户感兴趣的接口,维护一个ConcreteState子类的实例
  • State(抽象状态类):定义一个接口以封装与Context的一个特定状态相关的行为
  • ConcreteState(具体状态类):实现抽象状态类,每一个子类实现一个与Context的一个状态相关的行为

2. 实现方式相关

问题:如何实现状态模式?

答案要点:

// 1. 定义抽象状态类
public abstract class State
{
protected Context context;
public void setContext(Context context) {
this.context = context;
}
public abstract void handleRequest();
}
// 2. 定义环境类
public class Context
{
private State currentState;
public void changeState(State newState) {
this.currentState = newState;
this.currentState.setContext(this);
}
public void request() {
currentState.handleRequest();
}
}
// 3. 实现具体状态类
public class ConcreteStateA
extends State {
@Override
public void handleRequest() {
System.out.println("状态A处理请求");
context.changeState(new ConcreteStateB());
}
}

3. 重难点问题

问题:状态模式与策略模式的区别?

答案要点:

问题:如何解决状态转换的复杂性问题?

答案要点:

// 1. 使用状态转换表
public class StateTransitionTable
{
private final Map<
State, Map<
String, State>
> transitions = new HashMap<
>();
public void addTransition(State from, String event, State to) {
transitions.computeIfAbsent(from, k ->
new HashMap<
>()).put(event, to);
}
public State getNextState(State currentState, String event) {
Map<
String, State> stateTransitions = transitions.get(currentState);
if (stateTransitions != null) {
return stateTransitions.get(event);
}
return null;
}
}
// 2. 使用状态机模式
public class StateMachine
{
private State currentState;
private final StateTransitionTable transitionTable;
public void handleEvent(String event) {
State nextState = transitionTable.getNextState(currentState, event);
if (nextState != null) {
changeState(nextState);
}
}
}

4. Spring中的应用

问题:Spring中如何使用状态模式?

答案要点:

// 1. 使用Spring StateMachine
@Configuration
@EnableStateMachine
public class StateMachineConfig
extends StateMachineConfigurerAdapter<
String, String> {
@Override
public void configure(StateMachineStateConfigurer<
String, String> states) throws Exception {
states
.withStates()
.initial("SI")
.state("S1")
.state("S2")
.end("SF");
}
@Override
public void configure(StateMachineTransitionConfigurer<
String, String> transitions) throws Exception {
transitions
.withExternal()
.source("SI").target("S1").event("E1")
.and()
.withExternal()
.source("S1").target("S2").event("E2");
}
}
// 2. 使用状态机服务
@Service
public class StateMachineService
{
@Autowired
private StateMachine<
String, String> stateMachine;
public boolean sendEvent(String event) {
return stateMachine.sendEvent(event);
}
}

5. 设计原则相关

问题:状态模式体现了哪些设计原则?

答案要点:

6. 实际应用场景

问题:状态模式适用于哪些场景?

答案要点:


使用总结

状态模式的优势

  1. 消除条件判断:用多态替代大量的条件判断
  2. 状态封装:将每个状态封装成独立的类
  3. 行为委托:将行为委托给当前状态对象
  4. 易于扩展:可以轻松添加新的状态

状态模式的缺点

  1. 复杂度增加:增加了系统的复杂度
  2. 状态转换:状态转换逻辑可能变得复杂
  3. 学习成本:需要理解状态模式的概念
  4. 过度设计:简单场景可能不需要使用

使用建议

  1. 复杂状态:只用于复杂的状态管理场景
  2. 状态转换:考虑状态转换的复杂性
  3. 并发安全:注意多线程环境下的状态安全
  4. 状态持久化:考虑状态的持久化需求

最佳实践

  1. 状态转换表:使用状态转换表管理复杂的状态转换
  2. 状态历史:记录状态转换的历史
  3. 并发安全:使用同步机制确保状态转换的线程安全
  4. 状态持久化:实现状态的持久化存储
  5. 单元测试:为状态模式编写完整的单元测试

与其他模式的对比

  1. 与策略模式:状态模式是状态转换,策略模式是算法选择
  2. 与命令模式:状态模式是状态管理,命令模式是请求封装
  3. 与观察者模式:状态模式是状态变化,观察者模式是状态通知

状态模式是一种有用的行为型设计模式,特别适用于需要管理复杂状态、消除条件判断、封装状态行为等场景。通过合理使用状态模式,可以大大提高代码的可维护性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/917140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IEEE出版】第五届网络通信与信息安全国际学术会议(ICNCIS 2025)

2025年第五届网络通信与信息安全国际学术会议(ICNCIS2025)将于2025年10月17-19日于哈尔滨召开。【连续四届EI、Scopus双检索 | 快至会后4个月EI检索】 【已签约IEEE出版申请,已上线IEEE官方列表会议!EI检索稳定有保…

第16章 Day19 Charles安装和使用---微信小程序逆向

Charles安装(三方抓包工具) Charles客户端下载: 官网地址:https://www.charlesproxy.com/download/ 选择适合自己的系统版本下载下载安装完成后激活 激活网站地址:https://www.zzzmode.com/mytools/charles/打开安…

定制网站 北京服务器上怎么搭建网站

一,工具简介 tcpconnect工具追踪执行活动TCP连接的内核函数(例如,通过connect()系统调用;accept()是被动连接)。 详细地说,tcpconnect通过钩住内核中的tcp_v4_connect和/或tcp_v6_connect函数来工作,这些函数是在尝试建立TCP连接时被调用的。当这些函数被调用时,tcpc…

如何让百度快速收录网页如何让百度快捷收录网页的方法

如何让百度快速收录网页如何让百度快捷收录网页的方法2025-09-25 15:15 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; di…

061_尚硅谷_算术运算符课堂练习

061_尚硅谷_算术运算符课堂练习1.练习1:97天假期,有xx个星期零xx天 2.练习2:华氏温度134.2转为摄氏度

DBLINK的创建和使用(总结)

DBLINK的创建和使用(总结) 目录DBLINK的创建和使用(总结)一、什么是 DBLINK?二、创建 DBLINK 的三种主要方式方式一:使用 tnsnames.ora 文件(最常用、最推荐)步骤 1:配置 tnsnames.ora 文件步骤 2:创建 DBLI…

Could not resolve host: mirrorlist.centos.org

执行 [root@localhost yum.repos.d]# yum install bind-utils时,报centos-release-scl-rh Could not resolve host: mirrorlist.centos.org; Unknown error解决上面问题[root@localhost ~]# cd /etc/yum.repos.d [roo…

axi 4k边界检测

在AXI4协议中,一个突发传输(burst transfer)不能跨越4KB的边界,为啥呢,因为我们认为每个slave设备通常是4KB对齐的,为了避免一次burst的传输可能越过目的slave这个风险,所以就定了这个规矩 更深的说,确保数据传…

GOSIM 开源出海工作坊:给开源创业者的忠告

“出海”两个字,在开源语境里不是浪漫叙事,而是生死抉择。在这个数字机遇无限的时代,开源不仅是技术创新的象征,更是全球商业扩张的关键驱动力。本次分享将带你走过开源项目从诞生到跨越国界、进入全球市场的完整历…

华为,让金融智能体月映千江 - 指南

华为,让金融智能体月映千江 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco…

轻量级架构决策记录工具 - ADR Tools

ADR Tools是一个基于Unix shell脚本的命令行工具,用于管理和维护架构决策记录(ADRs)。它支持创建、更新和链接决策文档,采用Markdown格式存储,可与版本控制系统完美集成。ADR Tools - 架构决策记录工具 项目描述 …

一文搞懂Flex弹性布局空间分配规则

自从Flex布局面世后,基本每个项目我都是使用FLex,特别是小程序端,官方就是主推的Flex布局,相比以前你得费一些周折的布局方式,现在都能轻轻松松实现,用的多但是有一些计算细节其实也是理解不是特别深的,最近在B…

“小身材的大心脏”——HT-AD3PS-1+ 在成都恒利泰的射频江湖里到底做了什么?

“小身材的大心脏”——HT-AD3PS-1+ 在成都恒利泰的射频江湖里到底做了什么?“小身材的大心脏”——HT-AD3PS-1+ 在成都恒利泰的射频江湖里到底做了什么? 最近帮客户做一套“又要轻、又要稳、还要耐得住高低温”的射…

AT_agc012_c [AGC012C] Tautonym Puzzle 题目分析

# AT_agc012_c [AGC012C] Tautonym Puzzle## 题目描述当字符串 $ x $ 满足以下条件时,称 $ x $ 为*好字符串*。- 条件:$ x $ 可以表示为某个长度不少于 $ 1 $ 的字符串 $ y $ 重复两次所得的字符串 $ yy $。例如,`a…

电子商务网站建设pdfwordpress怎么重新安装

文章目录 一、初识TypeScript1、安装TypeScript2、Hello TypeScript 二、结合项目---配置1、tsconfig.jsontsconfig.json 重要字段compilerOptions 每个选项的详细说明 2、ts-loader 三、语法1、基本类型2、类型注解3、函数4、接口5、类6、泛型 四、结合项目---vue3结合使用 一…

详细介绍:回调函数与错误处理

详细介绍:回调函数与错误处理pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

Django系列(七)HttpRequest(请求)和HttpResponse(响应)对象

一、概述 Django 使用请求和响应对象在系统中传递状态。 当一个页面被请求时,Django 会创建一个 HttpRequest 对象,这个对象包含了请求的元数据。然后,Django 加载相应的视图,将 HttpRequest 作为视图函数的第一个…

值得收藏!GraphRAG:助力大模型突破“健忘”困局,构建逻辑化升级

值得收藏!GraphRAG:助力大模型突破“健忘”困局,构建逻辑化升级pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "…

工业主板:智能制造与严苛环境的坚实基石

在自动化生产线的精细控制、智能交通系统的稳定运行、医疗影像设备的可靠运转背后,工业主板扮演着不可或缺的重要角色。它不同于我们日常使用的消费级电脑主板,是为应对复杂严苛的工业环境而生的”专业心脏”。理解工…

12建网站电商眼

1.must :相当于and 2.must_not :相当于not 3.should:相当于or 4. filter:过滤 gte 大于 gt大于 lte小于等于 lt小于 使用示例&#xff1a; {“bool”:{“must”:{“match”:{“title”:”how to make millons “}},“must_not”:{“match”:{“tag”:”spam“}},“should”:[{…