动机
- 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
- 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转换间引入紧耦合?
模式定义
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
重点是提取出影响每种状态变化的行为;
每种状态负责切换到下一个正确的状态,状态类自己管理自己的状态切换。
类图
总结
- State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
- 为不同的状态引入不同的对象使得状态转换变的更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的一一即要么彻底转换过来,要么不转换。
- 可以使用单列模式,各个上下文共享同一个State对象,从而节省对象开销。
实例
场景:
订单状态和订单的一系列行为
- 提取订单的行为和具体的状态的切换状态,重点就是每个具体的订单状态在作为自己的行为后需要辅助自己的下一个状态,也就是切换状态。
public abstract class AbstractOrderState {
private AbstractOrderState nextState;
public AbstractOrderState getNextState() {
return nextState;
}
public void setNextState(AbstractOrderState nextState) {
this.nextState = nextState;
}
// 下面是影响订单的具体行为,而不订单状态。
// 抽取影响订单的行为,作为借口,每个具体的订单状态来实现这个接口
// 强调每个订单状态类负责自己的状态转换
public abstract void createOrder();
public abstract void payOrder();
public abstract void deliveryOrder();
public abstract void finishOrder();
public abstract void queryState();
}
- 实现订单具体的状态和对应的行为,订单状态负责自己切换状态
public class CreateState extends AbstractOrderState {
private volatile static AbstractOrderState singleInstance = null;
private CreateState() {
}
// 使用单列模式
public static AbstractOrderState getSingleInstance() {
if (singleInstance == null) {
synchronized (CreateState.class) {
if (singleInstance == null) {
singleInstance = new CreateState();
}
}
}
return singleInstance;
}
@Override
public void createOrder() {
System.out.println("Create order");
setNextState(PayState.getSingleInstance());
}
@Override
public void payOrder() {
System.out.println("Create state, can't pay");
setNextState(this);
}
@Override
public void deliveryOrder() {
System.out.println("Create state, can't deliveryOrder");
setNextState(this);
}
@Override
public void finishOrder() {
System.out.println("Create state, can't finishOrder");
setNextState(FinishState.getSingleInstance());
}
@Override
public void queryState() {
System.out.println("Create state");
setNextState(this);
}
}
public class DeliveryState extends AbstractOrderState {
private volatile static AbstractOrderState singleInstance = null;
private DeliveryState() {
}
// 使用单列模式
public static AbstractOrderState getSingleInstance() {
if (singleInstance == null) {
synchronized (DeliveryState.class) {
if (singleInstance == null) {
singleInstance = new DeliveryState();
}
}
}
return singleInstance;
}
@Override
public void createOrder() {
System.out.println("Delivery state, can't createOrder");
setNextState(this);
}
@Override
public void payOrder() {
System.out.println("Delivery state, can't pay");
setNextState(this);
}
@Override
public void deliveryOrder() {
System.out.println("Delivery Order");
setNextState(FinishState.getSingleInstance());
}
@Override
public void finishOrder() {
System.out.println("Delivery state, can't finishOrder");
setNextState(this);
}
@Override
public void queryState() {
System.out.println("Delivery state");
setNextState(this);
}
}
public class FinishState extends AbstractOrderState {
private volatile static AbstractOrderState singleInstance = null;
private FinishState() {
}
// 使用单列模式
public static AbstractOrderState getSingleInstance() {
if (singleInstance == null) {
synchronized (FinishState.class) {
if (singleInstance == null) {
singleInstance = new FinishState();
}
}
}
return singleInstance;
}
@Override
public void createOrder() {
System.out.println("Finish state, can't create order");
setNextState(this);
}
@Override
public void payOrder() {
System.out.println("Finish state, can't pay");
setNextState(this);
}
@Override
public void deliveryOrder() {
System.out.println("Finish state, can't deliveryOrder");
setNextState(this);
}
@Override
public void finishOrder() {
System.out.println("Finish state, can't finishOrder");
setNextState(this);
}
@Override
public void queryState() {
System.out.println("Finish state");
setNextState(this);
}
}
public class PayState extends AbstractOrderState {
private volatile static AbstractOrderState singleInstance = null;
private PayState() {
}
// 使用单列模式
public static AbstractOrderState getSingleInstance() {
if (singleInstance == null) {
synchronized (PayState.class) {
if (singleInstance == null) {
singleInstance = new PayState();
}
}
}
return singleInstance;
}
@Override
public void createOrder() {
System.out.println("Pay state, can't create order");
setNextState(this);
}
@Override
public void payOrder() {
System.out.println("Pay order");
setNextState(DeliveryState.getSingleInstance());
}
@Override
public void deliveryOrder() {
System.out.println("Pay state, can't deliveryOrder");
}
@Override
public void finishOrder() {
System.out.println("Finish order");
setNextState(FinishState.getSingleInstance());
}
@Override
public void queryState() {
System.out.println("Pay state");
setNextState(this);
}
}
- 状态处理类,一个稳定的框架,实现订单的行为。
// 订单处理上下文,稳定不变
public class OrderProcess {
private AbstractOrderState state;
public OrderProcess(AbstractOrderState state) {
this.state = state;
}
public void setState(AbstractOrderState state1) {
state = state1;
}
public void createOrder() {
state.createOrder();
state = state.getNextState();
}
public void payOrder() {
state.payOrder();
state = state.getNextState();
}
public void deliveryOrder() {
state.deliveryOrder();
state = state.getNextState();
}
public void finishOrder() {
state.finishOrder();
}
public void queryState() {
state.queryState();
}
}
- 客户端使用类
public class Client {
public static void main(String[] args) {
OrderProcess process = new OrderProcess(CreateState.getSingleInstance());
process.deliveryOrder();
process.createOrder();
process.payOrder();
process.deliveryOrder();
process.finishOrder();
}
}