• 设计模式


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

    • 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,愿同您为友

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

  • 相关阅读:
    Entity Framework 异常: 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。 关键字 'AS' 附近有语法错误。
    C#开源大全--汇总(转)
    C#开源系统大汇总(转)
    迁移博客园文章通知
    kickstart配置LINUX无人值守选项--rootpw
    linux 系统网卡无法识别,缺少驱动
    NFS服务简介
    linux下vim命令详解
    vim 中替换命令
    在CentOS/RHEL 6.4上安装Chromium
  • 原文地址:https://www.cnblogs.com/kiqi/p/14070787.html
Copyright © 2020-2023  润新知