我试图在当前的代码库中重构一个基于开关大小写的状态转换。现在添加更多的状态很痛苦(已经有10+),有多个地方有if-else/switch案例,在决定某些操作之前检查状态。
其思想是在spring中使用状态模式,状态表示为单例springbean,上下文表示当前转换。
每个状态都有一组在到达之前执行的转换操作,这在状态接口中表示
public interface State {
StateContext transformFrom(StateContext stateContext);
}
状态上下文表示当前状态和对其执行状态转换的业务实体
public class StateContext {
private State currentState;
private PersistentBusinessEntity businessEntity;
}
单个状态bean可以单独创建,也可以在公共bean配置中创建
@Configuration
public class StateBeanConfiguration {
@Bean("STATE_ONE")
public State transitionToStateOne(){
return (StateContext context)->{
//do state transformation
};
}
@Bean("STATE_TWO")
public State transitionToStateTwo(){
return (StateContext context)->{
//do state transformation
};
}
}
状态bean被Map到一个状态管理器中,该管理器执行状态之间Map的实际工作
public class StateManager {
// Auto-injected state map
Map<String, State> stateMap;
public State getStateFromName(String stateName){
return stateMap.get(stateName);
}
public StateContext transitionState(StateContext stateContext, State targetState){
targetState.transformFrom(stateContext);
stateContext.setCurrentState(targetState);
return stateContext;
}
}
现在要转换状态,可以请求管理器从当前状态Map到目标状态。
public void updateStateForBusinessObject(PersistentBusinessEntity entity,
StateChangeRequest stateChangeRequest){
State currentState = stateManager.getStateFromName(entity.currentState);
StateContext stateContext = new StateContext(currentState, entity);
State targetState = stateManager.getStateFromName(stateChangeRequest.stateChangeTo);
stateManager.transitionState(stateContext, targetState);
}
为了简洁起见,减少了代码,但是实际的实现有更多的注意事项,包括链接状态转换。这个 updateStateForBusinessObject
方法将在http客户端请求时调用。
spring以这种方式设计状态有什么问题吗,特别是在每个请求上创建上下文和引用singletonbean对象。我在别处读到过,应该为每个转换请求创建states对象,但这似乎是一种浪费,因为实际的statebean不包含请求状态。
我该如何改进?
暂无答案!
目前还没有任何答案,快来回答吧!