状态模式允许其内部状态发生变化的时候改变其行为,貌似是对象改变了类。
一个对象的行为取决于一个或者多个动态变化的属性,这些属性叫做状态,比如订单的支付状态;而这些订单状态的值是预先知道的,已支付、未支付;当订单在客户操作过程中可能会改变支付状态,订单从未支付到已支付,就形成订单真正成功下单。
适用场景:
- 一个对象的行为取决于他的状态,并且它必须在运行时根据状态改变它的行为;
- 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。
先看下 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 方法中需要做一些持久化操作和业务校验,也许更加符合业务需要。