spring中带有注解的java状态模式

jbose2ul  于 2021-07-14  发布在  Java
关注(0)|答案(0)|浏览(391)

我试图在当前的代码库中重构一个基于开关大小写的状态转换。现在添加更多的状态很痛苦(已经有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不包含请求状态。
我该如何改进?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题