• java设计模式(十四)——状态模式


    1、基本概念

    状态模式( State Pattern )也称为状态机模式(State Machine Pattern) ,是允许对象在内
    部状态发生改变时改变它的行为,对象看起来好像修改了它的类,属于行为型模式。

    场景实例:订单的状态改变,工作流程的状态改变

    2、类图和角色

    类图:

     看起来和策略模式很像,抽象,具体,上下文三个对象

    角色:

    上下文context : 负责维护一个当前状态对象和具体实例状态的切换

    抽象状态类:定义状态下的行为

    具体状态类:具体状态下行为的实现,并进行状态的切换

    3、案例

    案例:一个app,用户评论一篇文章,如果用户没有登录,就让其跳转到登录页面进行登录,成功后,切换当前的状态位已登录用户

    示意图:

     类图:

    抽象状态:接口IUserStatus,定义一个统一的接口方法

    public interface IUserStatus {
    
        void comment(String msg);
    
    }

    抽象状态:抽象类UserStatus

    public abstract class UserStatus implements IUserStatus{
    
        protected Context context;
    
        public void setContext(Context context){
            this.context = context;
        }
        public abstract void comment(String msg);
    }

    具体抽象:登录状态类LoginStatus 

    public class LoginStatus extends UserStatus {
    
        @Override
        public void comment(String msg) {
            System.out.println("登录用户xxx:"+msg);
        }
    }

    具体抽象:未登录状态类NoLoginStatus ,执行comment方法前,进行状态的切换

    public class NoLoginStatus extends UserStatus {
        @Override
        public void comment(String msg) {
            //进行登录后才可评论
            System.out.println("系统信息:当前用户未登录,请前往登录");
            toLoginOn();
            this.context.getCurrentUserStatus().comment(msg);
        }
    
        public void toLoginOn() {
            //登录,修改状态
            this.context.setUserStatus(context.LOGIN_STATUS);
            System.out.println("系统信息:登录成功");
        }
    }

    上下文:Context ,负责状态的切换与获取

    public class Context {
        public static final LoginStatus LOGIN_STATUS = new LoginStatus();
        public static final NoLoginStatus NO_LOGIN_STATUS =new NoLoginStatus();
    
        private UserStatus currentUserStatus = NO_LOGIN_STATUS;
    
        public Context(){
            LOGIN_STATUS.setContext(this);
            NO_LOGIN_STATUS.setContext(this);
        }
    
        public void setUserStatus(UserStatus userStatus){
            this.currentUserStatus = userStatus;
            this.currentUserStatus.setContext(this);
        }
    
        public UserStatus getCurrentUserStatus(){
            return this.currentUserStatus;
        }
    }

    测试:

    public class Test {
        public static void main(String[] args) {
            Context context = new Context();
            UserStatus userStatus = new NoLoginStatus();
            userStatus.setContext(context);
            userStatus.comment("老铁,666");
        }
    }

    输出结果:

    系统信息:当前用户未登录,请前往登录
    系统信息:登录成功
    登录用户xxx:老铁,666

    4、优缺点

    优点;

    1、结构清晰,可以干掉if..else语句, 使代码更加简洁
    2、状态类职责明确且具备扩展性。

    缺点:不符合开闭原则,当我们需要新增一个管理员状态的对象,就需要在登陆的时候切换状态,

    那么我们就需要修改context中的代码和LoginStatus的代码

  • 相关阅读:
    javasrcipt array 码农
    touch事件与click事件 码农
    sqlite note 码农
    JSONP原理及自定义JSONP函数 码农
    阿里云ECS部署单机kafka 并对外提供服务(带认证)
    vue组件为什么要用data函数
    引导页的设置
    charles for centos 实现map local/map remote功能
    关于宝塔会自动上传网站访问数据的问题
    .Net 【Winform】 BackgroundWorker总结
  • 原文地址:https://www.cnblogs.com/tdyang/p/13356479.html
Copyright © 2020-2023  润新知