zoukankan      html  css  js  c++  java
  • 设计模式

    状态模式:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
    核心:当前状态决定当前行为,行为执行后又可能导致状态的转换
    角色:

    • Context上下文容器:维护所有的状态和行为,是面向客户的入口
    • Status对象:保存状态对应的行为。
    • Machine状态机:维护状态的转换关系when(行为,状态) -> next状态:do(next行为)

    由status对象在行为中完成状态转换

    Context

    // 上下文信息,用于维护所有状态对象以及当前状态信息,同时作为客户端的访问入口
    public class Context implements IStatus{
        // 更正一下设计模式之禅中对状态机的示例:其状态对象使用了final static,但是状态对象又持有了context对象引用,必然会出现并发问题
        protected final IStatus OPEN = new OpenStatus(this);
        protected final IStatus STOP_CLOSE = new StopStatus(this);
        protected final IStatus RUN = new RunStatus(this);
    
        private IStatus status = null;
    
        public Context() {
            this.status = STOP_CLOSE;
        }
    
        protected void setStatus(IStatus status) {this.status = status;}
    
        // 具体行为委托给status对象执行
        @Override
        public void run() {this.status.run();}
    
        @Override
        public void stop() {this.status.stop();}
    
        @Override
        public void open() {this.status.open();}
    
        @Override
        public void close() {this.status.close();}
    }
    

    Status

    // 抽象状态对象,提供公共的默认实现(由于在状态内部进行状态流转,因此还需持有context上下文信息)
    public abstract class AbstractStatus implements IStatus{
    
        protected Context context = null;
    
        protected AbstractStatus(Context context){
            this.context = context;
        }
    
        @Override
        public void run() {System.out.println("command run - Do nothing!");}
    
        @Override
        public void stop() {System.out.println("command stop - Do nothing!");}
    
        @Override
        public void open() {System.out.println("command open - Do nothing!");}
    
        @Override
        public void close() {System.out.println("command close - Do nothing!");}
    }
    
    // 子类负责具体实现逻辑,重写该状态下支持的行为,并设置状态转换。
    public class OpenStatus extends AbstractStatus{
        public OpenStatus(Context context) {
            super(context);
        }
    
        @Override
        public void open() {
            System.out.println("command open - keep open");
        }
    
        @Override
        public void close() {
            System.out.println("command close - close the door");
            this.context.setStatus(this.context.STOP_CLOSE);
        }
    }
    

    状态机实现状态模式

    Context

    // 用于维护当前状态信息,以及使用状态机完成状态转换,作为客户端的访问入口
    public class Context implements IStatus {
        private AbstractStatus status = null;
    
        public Context() {
            this.status = StatusMechine.STOP_CLOSE_STATUS;
        }
    
        protected void setStatus(AbstractStatus status) {
            this.status = status;
        }
    
        // 将命令委托给具体的状态对象进行处理,并将当前状态和执行行为交由状态机完成状态转换
        @Override
        public void run() {
            this.status.run();
            this.status = StatusMechine.trans(this.status,StatusMechine.RUN_ACTION);
        }
    
        @Override
        public void stop() {
            this.status.stop();
            this.status = StatusMechine.trans(this.status,StatusMechine.STOP_ACTION);
        }
    
        @Override
        public void open() {
            this.status.open();
            this.status = StatusMechine.trans(this.status,StatusMechine.OPEN_ACTION);
        }
    
        @Override
        public void close() {
            this.status.close();
            this.status = StatusMechine.trans(this.status,StatusMechine.CLOSE_ACTION);
        }
    }
    

    StatusMechine

    public class StatusMechine{
        // 行为类型
        protected final static String RUN_ACTION = "RUN";
        protected final static String STOP_ACTION = "STOP";
        protected final static String OPEN_ACTION = "OPEN";
        protected final static String CLOSE_ACTION = "CLOSE";
    
        // 状态类型
        protected final static AbstractStatus OPEN_STATUS = new OpenStatus();
        protected final static AbstractStatus STOP_CLOSE_STATUS = new StopStatus();
        protected final static AbstractStatus RUN_STATUS = new RunStatus();
    
        // 状态流转表
        protected static Map<String,AbstractStatus> transMap = new HashMap<>();
    
        // 状态转换
        public static AbstractStatus trans(AbstractStatus status, String actions) {
            String key = status.getStatusName() + actions;
            return transMap.getOrDefault(key, status);
        }
    
        // 状态转换过程注册方法
        protected static void registerStatusTrans(AbstractStatus status, String action, AbstractStatus nextStatus){
            transMap.put(status.getStatusName() + action, nextStatus);
        }
    
        // 将状态的转换注册到状态机中
        static {
            StatusMechine.registerStatusTrans(StatusMechine.RUN_STATUS, StatusMechine.STOP_ACTION, StatusMechine.STOP_CLOSE_STATUS);
            StatusMechine.registerStatusTrans(StatusMechine.STOP_CLOSE_STATUS, StatusMechine.RUN_ACTION, StatusMechine.RUN_STATUS);
            StatusMechine.registerStatusTrans(StatusMechine.STOP_CLOSE_STATUS, StatusMechine.OPEN_ACTION, StatusMechine.OPEN_STATUS);
            StatusMechine.registerStatusTrans(StatusMechine.OPEN_STATUS, StatusMechine.CLOSE_ACTION, StatusMechine.STOP_CLOSE_STATUS);
        }
    }
    

    Status

    // 抽象状态对象,提供公共的默认实现
    public abstract class AbstractStatus implements IStatus {
        public abstract String getStatusName();
    
        @Override
        public void run() {System.out.println("command run - Do nothing!");}
    
        @Override
        public void stop() {System.out.println("command stop - Do nothing!");}
    
        @Override
        public void open() {System.out.println("command open - Do nothing!");}
    
        @Override
        public void close() {System.out.println("command close - Do nothing!");}
    }
    
    // 具体实现子类,只需专注于具体指令的实现逻辑,而无需关心状态转换过程
    public class OpenStatus extends AbstractStatus {
        @Override
        public String getStatusName() {
            return "OPEN";
        }
    
        @Override
        public void open() {
            System.out.println("command open - keep open");
        }
    
        @Override
        public void close() {
            System.out.println("command close - close the door");
        }
    }
    

    欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友

    -- 星河有灿灿,愿与之辉

  • 相关阅读:
    ArrayList removeRange方法分析
    LinkedHashMap源码分析(基于JDK1.6)
    LinkedList原码分析(基于JDK1.6)
    TreeMap源码分析——深入分析(基于JDK1.6)
    51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划
    51 NOD 1049 最大子段和 动态规划 模板 板子 DP
    51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
    8月20日 训练日记
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/kiqi/p/14070787.html
Copyright © 2011-2022 走看看