Spring 中带有注释的状态模式

问题描述

我正在尝试重构当前代码库中基于 switch-case 的状态转换。现在添加更多状态很痛苦(已经有 10 多个),有很多地方有 if-else/switch 情况,可以在决定某些操作之前检查状态。

这个想法是在 spring 中使用状态模式,状态表示为单例 spring bean,上下文表示当前转换。

每个状态在到达之前都有一组转换操作,这在状态接口中表示

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 被映射到一个状态管理器中,它完成状态之间映射的实际工作

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;
    }
}

现在要转换状态,可以只要求管理器从当前状态映射到目标状态。

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 以这种方式设计状态是否存在任何问题,特别是在每个请求上创建上下文并引用单例 bean 对象。我在别处读到应该为每个转换请求创建状态对象,但这似乎是一种浪费,因为实际的状态 bean 不保存请求状态。

我该如何改进?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)