微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring 中带有注释的状态模式

如何解决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 举报,一经查实,本站将立刻删除。