Java设计模式Java学习笔记

设计模式-状态模式

2016-11-16  本文已影响801人  breezedancer

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

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

适用场景:

先看下 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 方法中需要做一些持久化操作和业务校验,也许更加符合业务需要。

上一篇 下一篇

猜你喜欢

热点阅读