设计模式-状态模式

状态模式允许其内部状态发生变化的时候改变其行为,貌似是对象改变了类。

一个对象的行为取决于一个或者多个动态变化的属性,这些属性叫做状态,比如订单的支付状态;而这些订单状态的值是预先知道的,已支付、未支付;当订单在客户操作过程中可能会改变支付状态,订单从未支付到已支付,就形成订单真正成功下单。

适用场景:

  • 一个对象的行为取决于他的状态,并且它必须在运行时根据状态改变它的行为;
  • 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

先看下 UML 类图

上下文类Context: 维护一个ConcreteState子类的实例,这个实例定义当前状态; 抽象状态类State: 定义一个接口以封装与Context的一个特定状态相关的行为; 具体状态类ConcreteState: 每一子类实现一个与Context的一个状态相关的行为;

模拟下订单的状态改变: 总共有未支付、已支付、申请退款,退款中,退款完成订单结束几个过程,过程中每个状态需要依赖上个状态,这个在本例中没有做判断,仅仅展示状态变化的魔力。 首先把订单状态这个抽象类给写出来

public abstract class OrderStatus {    protected Order order;    protected String name;    public OrderStatus(Order order,String name) {        this.order=order;        this.name=name;
    }    public abstract OrderStatus next(Order order);    public void print(){
        System.out.println("当前状态"+this.name);
    }
}

然后把订单类写出

public class Order {    private OrderStatus status;    public OrderStatus getStatus() {        return status;
    }    public void setStatus(OrderStatus status) {        this.status = status;
    }//other properties}

他们之间是秤不离砣,你中有我,我中有你; 接下来看下具体的状态: 第一个是没有支付的状态,也就是订单默认状态,甚至可以初始化到订单内部,这里也单独拿出来

public class NoPayStatus extends OrderStatus{    public NoPayStatus(Order order,String name) {        super(order,name);
    }    @Override
    public OrderStatus next(Order order) {
        print();
        OrderStatus s=new PayStatus(order,"已支付");
        order.setStatus(s);        return s;
    }

}

第二,已支付状态

public class PayStatus extends OrderStatus {    public PayStatus(Order order, String name) {        super(order, name);
    }    @Override
    public OrderStatus next(Order order) {
        print();        return new ApplyDrawbackStatus(order, "申请退款");

    }

}

第三是申请退款,第三部可以根据实际业务情况直接到第五状态

public class ApplyDrawbackStatus extends OrderStatus {    public ApplyDrawbackStatus(Order order, String name) {        super(order, name);
    }    @Override
    public OrderStatus next(Order order) {
        print();        return new DrawbackStatus(order, "订单回款中");

    }

}

第四是退款中

public class DrawbackStatus extends OrderStatus {    public DrawbackStatus(Order order, String name) {        super(order, name);
    }    @Override
    public OrderStatus next(Order order) {
        print();        return new CompleteStatus(order, "订单回款完成,彻底结束");

    }

}

第五是订单彻底完成

public class CompleteStatus extends OrderStatus {    public CompleteStatus(Order order, String name) {        super(order, name);
    }    @Override
    public OrderStatus next(Order order) {
        print();        return null;

    }

}

最后看下客户端

public class Client {    public static void main(String[] args) {
        Order order=new Order();
        order.setStatus(new NoPayStatus(order, "未支付"));
        OrderStatus status=order.getStatus();
        status=status.next(order);
        System.out.println("---------------");
        status=status.next(order);
        System.out.println("---------------");
        status=status.next(order);
        System.out.println("---------------");
        status=status.next(order);
        System.out.println("---------------");
        status=status.next(order);
    }

}/**  ----Result----
当前状态未支付
---------------
当前状态已支付
---------------
当前状态申请退款
---------------
当前状态订单回款中
---------------
当前状态订单回款完成,彻底结束
*/

客户端需要校验空指针,这里不再赘述.

订单状态改变,也就是在 next 方法中需要做一些持久化操作和业务校验,也许更加符合业务需要。

本文分享自微信公众号 - 技术与生活(technology_life)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分布式系统和大数据处理

C#网络编程(订立协议和发送文件) - Part.4

前面两篇文章所使用的范例都是传输字符串,有的时候我们可能会想在服务端和客户端之间传递文件。比如,考虑这样一种情况,假如客户端显示了一个菜单,当我们输入S1、S2...

11510
来自专栏圣杰的专栏

ASP.NET Core 中断请求了解一下(翻译)

假设有一个耗时的Action,在浏览器发出请求返回响应之前,如果刷新了页面,对于浏览器(客户端)来说前一个请求就会被终止。而对于服务端来说,又是怎样呢?前一个请...

16230
来自专栏大内老A

如果你想深刻理解ASP.NET Core请求处理管道,可以试着写一个自定义的Server

我们在上面对ASP.NET Core默认提供的具有跨平台能力的KestrelServer进行了详细介绍(《聊聊ASP.NET Core默认提供的这个跨平台的服务...

25080
来自专栏jeremy的技术点滴

sed命令工作原理及命令备忘

36390
来自专栏大内老A

WCF后续之旅(6): 通过WCF Extension实现Context信息的传递

在上一篇文章中,我们讨论了如何通过CallContextInitializer实现Localization的例子,具体的做法是将client端的culture通...

21870
来自专栏跟着阿笨一起玩NET

ASP.NET中DesignMode属性

参考:http://blog.sina.com.cn/s/blog_4c9da9b50100r4u7.html

11320
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第4章 global全局变量

global 全局变量 global用来定义全局变量,它可以让应用程序的对象在规则文件中能够被访问。通常,可以用来为规则文件提供数据或服务。特别是用来操作规则执...

34160
来自专栏大内老A

WCF技术剖析之一:通过一个ASP.NET程序模拟WCF基础架构

细算起来,已经有好几个月没有真正的写过文章了。近半年以来,一直忙于我的第一本WCF专著《WCF技术剖析》的写作,一直无暇管理自己的Blog。到目前为止《WCF技...

29070
来自专栏网络

HttpClient使用心得

做过Java web开发的朋友们,应该大部分都用过Apatch HttpClient工具类库,最近在维护公司一个老项目时,遇到了由于HttpClient使用不当...

43790
来自专栏晓晨的专栏

ASP.NET Core 添加统一模型验证处理机制

22950

扫码关注云+社区

领取腾讯云代金券