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上。

    未完待续....

  • 相关阅读:
    KMP的next
    关于codeblocks左边文件栏不见的问题
    数据结构第二章内容
    设置notepad++ 的 tab 设为4个空格和设置为中文语言
    字面量
    ..没什么
    今天做的HTML练习
    DAY 145 django的聚合函数和aggregate、annotate方法使用
    DAY 144 Math.round()/Math.ceil()/Math.floor()差异
    DAY 143 DRF-Django rest framework
  • 原文地址:https://www.cnblogs.com/markytsai/p/13366096.html
Copyright © 2011-2022 走看看