从电商系统订单状态说状态模式!

JAVA herman 538浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

状态模式,听过的人可能不是很多,它不在我们熟知的 23 中设计模式之内。但它归属与行为型模式中的一种。今天我们一起来学习学习状态模式!

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。通常我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

状态模式最大的优点是:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

主要解决的问题是:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

使用场景:代码中包含大量与对象状态有关的条件语句。

如何使用,下面我们通过一个订单的状态来看一个实例。

在电商系统,购物过程中,订单一般有这几种状态,待付款,待出库,待评价,完成。不同的状态下,用户看到的提示信息是不同的(行为不同)。

订单状态模式类图

根据上面的类图,我们先来实现一个抽象状态接口。

public interface OrderState{
    void action(Context context);
    void doPrint();
}

待付款实现类。

public class PendingPaymentState implements OrderState{
    @Override
    public void action(Context context){
        context.setOrderState(new WaitOutStockState());
    }
    @Override
    public void doPrint(){
        System.out.println("处理待付款状态的逻辑");
    }
}

待出库状态。

public class WaitOutStockState implements OrderState{
    @Override
    public void action(Context context){
        context.setOrderState(new PendingDeliveryOrder());
    }
    @Override
    public void doPrint(){
        System.out.println("等待出库状态");
    }
}

待收货状态。

public class PendingDeliveryOrder implements OrderState{
    @Override
    public void action(Context context){
        context.setOrderState(new PendingEvaluation());
    }
    @Override public void doPrint(){
        System.out.println("待收货状态");
    }
}

待评价状态。

public class PendingEvaluation implements OrderState{
    @Override
    public void action(Context context){
        context.setOrderState(new CompletedOrder());
    }
    @Override 
    public void doPrint(){
        System.out.println("待评价状态");
    }
}

订单完成状态。

public class CompletedOrder implements OrderState{
    @Override
    public void action(Context context){
        context.setOrderState(null);
    }
    @Override 
    public void doPrint(){
        System.out.println("订单完成状态");
    }
}

Context 类,订单状态变化引起行为变化。

public class Context{
    private OrderState orderState;
    public Context(OrderState orderState){
        this.orderState = orderState;
    }
    public void setOrderState(OrderState orderState){
        this.orderState = orderState;
    }
    public void action(){
        this.orderState.action(this);
    }
    public void printInfo(){
        if (this.orderState != null){
            this.orderState.doPrint();
        }
    }
}

下面使用 XttblogOrderDemo 类,模拟一下生产环境中的使用场景。

public class XttblogOrderDemo{
    public static void main(String[] args){
        OrderState orderState = new PendingPaymentState();
        Context context = new Context(orderState);
        context.printInfo();

        //用户付款
        context.action();
        context.printInfo();

        //商家出库发货
        context.action();
        context.printInfo();

        //用户签收
        context.action();
        context.printInfo();

        //用户评价
        context.action();
        context.printInfo();
    }
}

总结下来,状态模式中涉及到 3 个角色。

  • 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
  • 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
  • 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

状态模式和策略模式的结构是比较相似的,但是两者却存在较大区别。策略模式是对算法或者策略建模,不涉及算法之间的切换。而状态模式是对状态进行建模,涉及状态之间的切换,其实就是状态机的模型,每种状态对应不同的处理逻辑。

状态模式在实际工作中非常的常用,比如:投票应用。一个在线投票系统的应用,要实现控制同一个用户只能投一票,如果一个用户反复投票,而且投票次数超过5次,则判定为恶意刷票,要取消该用户投票的资格,当然同时也要取消他所投的票;如果一个用户的投票次数超过8次,将进入黑名单,禁止再登录和使用系统。要使用状态模式实现,首先需要把投票过程的各种状态定义出来,根据以上描述大致分为四种状态:正常投票、反复投票、恶意刷票、进入黑名单。

叫号系统,取号,排队等待,办理业务,评价等。在比如游戏中的不同动作等。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 从电商系统订单状态说状态模式!