zoukankan      html  css  js  c++  java
  • 设计模式之-状态模式

    最近接手了一个发布系统的开发需求,根据设计原型图,可以初步看出来是一个过程流转的过程,所以想到了用状态机模式来实现。

    一个简单的发布会包括这些流程,每一个节点的执行取决于上一个节点的执行结果。如果上一个节点执行成功,则流转到下一个节点;如果上一个异常,则直接流转到异常状态,最终都会到达完成状态。所以完成的标志会是成功和异常两种来区分。

    状态模式需要一个状态接口,还有一系列具体的状态实现类,这些类对应着状态流转图中的各个节点,需要做的事情可以放在具体的实现类中去。

    public interface StateMachine {
    void transferState(State state, Context context); }

    StateMachine接口负责定义状态流转的动作,实现类需要实现方法,并且保证流程能够向后流转。

    public class PreCompileState implements StateMachine {
    
        @Override
        public void transferState(State state, Context context) {
            StateHandler handler = StateManager.getHandler(context);
            handler.handle(context);
        }
    }
    public class CompileState implements StateMachine {
    
        @Override
        public void transferState(State state, Context context) {
            StateHandler handler = StateManager.getHandler(context);
            handler.handle(context);
        }
    }
    public class ExceptionState implements StateMachine {
    
        @Override
        public void transferState(State state, Context context) {
            StateHandler handler = StateHandlerManager.getHandler(context);
            handler.handle(context);
        }
    }
    public class FinishState implements StateMachine {
    
        @Override
        public void transferState(State state, Context context) {
            StateHandler handler = StateHandlerManager.getHandler(context);
            handler.handle(context);
        }
    }

    每个实现类都只负责该状态下自己的事情,拿到自己状态的handler进行实际的业务处理。

    现在看下StateHandlerManager管理类做了什么。

    public class StateHandlerManager {
    
        private static Map<State, Class<?>> clazzMap = new HashMap<>();
    
        public static void trigger(Context context) {
    
            StateHandler handler = getHandler(context);
    
            assert handler != null;
    
            handler.handle(context);
        }
    
        public static StateHandler getHandler(Context context) {
            StateHandler handler = getHandler(context.getState());
            if (handler == null) {
                init();
            }
            return getHandler(context.getState());
        }
    
        public static void init() {
            clazzMap.put(State.PRE_COMPILE, PreCompileHandler.class);
            clazzMap.put(State.COMPILE, CompileHandler.class);
            clazzMap.put(State.BACKUP, BackupHandler.class);
            clazzMap.put(State.SQL_EXECUTION, SqlExecutionHandler.class);
            clazzMap.put(State.DEPLOY, DeployHandler.class);
            clazzMap.put(State.FINISH, FinishHandler.class);
            clazzMap.put(State.EXCEPTION, ExceptionHandler.class);
        }
    
        public static StateHandler getHandler(State state) {
            Class<?> clazz = clazzMap.get(state);
            if (clazz == null) {
                return null;
            }
            return BeanHolder.getBean(clazz);
        }
    }

     Handler做的事情如下

    public interface StateHandler<T> {
    
        /**
         * @param t
         */
        void handle(T t);
    }

    这些状态节点维护了自己的业务,接下来就需要状态流转。异常处理如何确定下一步流程,其他具体流转的规则需要自己定义。之后会把源码放到GitHub上。

    未完待续....

  • 相关阅读:
    poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
    poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
    poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
    hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)
    hdu 1025 上面n个点与下面n个点对应连线 求最多能连有多少条不相交的线 (LIS)
    Gym 100512F Funny Game (博弈+数论)
    UVa 12714 Two Points Revisited (水题,计算几何)
    UVa 12717 Fiasco (BFS模拟)
    UVa 12718 Dromicpalin Substrings (暴力)
    UVa 12716 && UVaLive 6657 GCD XOR (数论)
  • 原文地址:https://www.cnblogs.com/markytsai/p/13366096.html
Copyright © 2011-2022 走看看