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