• 状态模式


    最近发现项目中的判断太多,大量的if-else结构,想着重构下,于是接触到了状态模式。
    这种设计模式就是java多态的体现,没有想象的那么神奇。

    状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

    1、有一个对象,它是有状态的。
    2、这个对象在状态不同的时候,行为不一样。
    3、这些状态是可以切换的,而非毫无关系。

    图中包含三个角色。
    Context:它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。
    State:状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。
    ConcreteState:具体状态,实现相关行为的具体状态类。
    其他解释
    环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
    抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
    具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

    个人还是喜欢把环境角色context带入接口的方法参数中,这样逻辑更清楚;
    另外的方式是把context放入各个具体状态角色的构造方法中,当实例化context的时候,通过具体状态的构造方法加载此context实例到具体状态角色中

    举例一
    本例子模拟购物的整个过程,包括下单,付款,收货,评价,退款,结束等。

    状态接口

    public interface Event {
        //下单
        void order(Shopping shopping,Boolean isConfirm) ;
        //付款
        void pay(Shopping shopping,Boolean isConfirm);
        //签收
        void receive(Shopping shopping,Boolean isConfirm);
        //评价
        void evaluate(Shopping shopping,Boolean isConfirm);
        //订单结束
        void finish(Shopping shopping,Boolean isConfirm);
        //退款
        void refund(Shopping shopping,Boolean isConfirm);
    }

    抽象类主要处理异常的情况,即用户重复提交某个状态时出现

    public  class AbstractEvent implements Event {
        @Override
        public void order(Shopping shopping, Boolean isConfirm) {
            System.out.println("亲亲,下单异常");
        }
    
        @Override
        public void pay(Shopping shopping, Boolean isConfirm) {
            System.out.println("亲亲,支付异常");
        }
    
        @Override
        public void receive(Shopping shopping, Boolean isConfirm) {
            System.out.println("亲亲,接收异常");
        }
    
        @Override
        public void evaluate(Shopping shopping, Boolean isConfirm) {
            System.out.println("亲亲,评价异常");
        }
    
        @Override
        public void finish(Shopping shopping, Boolean isConfirm) {
            System.out.println("亲亲,结束操作流程错误");
        }
    
        @Override
        public void refund(Shopping shopping, Boolean isConfirm) {
            System.out.println("您的订单已经退款,请不要重复提交");
        }
    }

    具体状态角色 - 下单

    public class Order extends AbstractEvent {
        @Override
        public void order(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("恭喜您,下单成功");
                shopping.setEvent(Shopping.PAY_STATE);//确定下单,进入支付页面
            }else {
                System.out.println("订单页面取消成功,回到主页面");
                shopping.setEvent(Shopping.REFUND);
            }
        }
    }

    具体状态角色 - 支付

    public class Pay extends AbstractEvent {
        @Override
        public void pay(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("恭喜您,支付成功");
                shopping.setEvent(Shopping.RECEIVE_STATE);//进入收货阶段
            }else {
                System.out.println("支付页面,取消订单成功");
                shopping.setEvent(Shopping.REFUND);
            }
        }
    }

    具体状态角色 - 接收

    public class Receive extends AbstractEvent {
        @Override
        public void receive(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("亲,签收物品成功,期待下次与您再次相见");
                shopping.setEvent(Shopping.EVALUATE_STATE);
            }else {
                System.out.println("亲,签收阶段退款成功");
                shopping.setEvent(Shopping.REFUND);
            }
        }
    }

    具体状态角色 - 评价

    public class Evaluate extends AbstractEvent {
        @Override
        public void evaluate(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("评价商品成功");
                shopping.setEvent(Shopping.FINISH_STATE);
            }else {
                System.out.println("评价阶段,退款成功");
                shopping.setEvent(Shopping.REFUND);
            }
        }
    }

    具体状态角色 - 完成

    public class Finish extends AbstractEvent {
        @Override
        public void finish(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("订单结束,感谢您的光临");
            }else {
                System.out.println("亲爱的客人,请您分享使用心得");
            }
        }
    }

    具体状态角色 - 退款

    public class Refund extends AbstractEvent {
        @Override
        public void refund(Shopping shopping, Boolean isConfirm) {
            if(isConfirm){
                System.out.println("抱歉客官,给您带来不好的购物体验了,已为您退款,请见谅");
                shopping.setEvent(Shopping.FINISH_STATE);
            }
        }
    }

    环境角色,有状态的对象 - 购物对象

    public class Shopping {
        public static final Event ORDER_STATE = new Order();
        public static final Event PAY_STATE = new Pay();
        public static final Event RECEIVE_STATE = new Receive();
        public static final Event EVALUATE_STATE = new Evaluate();
        public static final Event FINISH_STATE = new Finish();
        public static final Event REFUND = new Refund();
        //状态记录,默认进入下单状态
        private Event event = ORDER_STATE;
    
        public Event getEvent() {
            return event;
        }    
        public void setEvent(Event event) {
            this.event = event;
        }
    
        public void startOrder(Boolean isConfirm){
            event.order(this,isConfirm);
        }
        public void startPay(Boolean isConfirm){
            event.pay(this,isConfirm);
        }
        public void startReceive(Boolean isConfirm){
            event.receive(this,isConfirm);
        }
        public void startEvaluate(Boolean isConfirm){
            event.evaluate(this,isConfirm);
        }
        public void startFinish(Boolean isConfirm){
            event.finish(this,isConfirm);
        }
        public void startRefund(Boolean isConfirm){
            event.refund(this,isConfirm);
        }
    }

    客户启动段

    public class Client {
        public static void main(String[] args) {
            Shopping shopping = new Shopping();
            //下单成功
            shopping.startOrder(true);
            shopping.startOrder(true);
            shopping.startOrder(true);
            shopping.startOrder(true);
            shopping.startOrder(true);
            shopping.startPay(true);
            shopping.startReceive(false);
            shopping.startRefund(true);
            shopping.startEvaluate(true);
            shopping.startFinish(true);
        }
    }

    运行结果:

    状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换,又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。

  • 相关阅读:
    你人生中的那口井挖了没有?
    SQL Server 中WITH (NOLOCK)浅析
    如何用SQL语句查询Excel数据?
    ASP.NET Core中的依赖注入(2):依赖注入(DI)
    ASP.NET Core中的依赖注入(1):控制反转(IoC)
    wx小程序的学习
    Mac OS 下安装mysql环境
    Mac 全局变量 ~/.bash_profile 文件不存在的问题
    延期风险原因总结
    homebrew osx下面最优秀的包管理工具
  • 原文地址:https://www.cnblogs.com/InternetJava/p/12540133.html
Copyright © 2020-2023  润新知