文章内容
一、什么是状态模式
状态模式,对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式,属于行为型设计模式。
二、状态模式类图
三、状态模式角色
- 抽象状态角色(State): 定义一个接口以封装使用上下文环境的一个特定状态相关的行为。
- 具体状态角色(ConcreteState): 实现抽象状态定义的接口。
- 环境角色(Context): 定义了客户端需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的ConcreteState对象来处理。
四、状态模式优缺点
1、优点
- 将所有与某个状态有关的行为放到一个类中,并且将不同状态的行为分割开来,满足“单一职责原则”。
- 将不同的状态引入单独的对象中会使得状态转换变得更加明确,减少对象间的相互依赖。
- 有利于程序的扩展。新增状态可以通过新增状态子类来完成,满足”开闭原则“。
2、缺点
- 增加了系统的类与对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
五、状态模式demo示例
1、Demo需求
以电商平台订单状态为例,使用状态模式实现订单状态流转,订单状态:待支付、待发货、已发货、已收货。
2、抽象类定义
/**
* @Description: 抽象状态角色:抽象订单状态类
**/ public abstract class OrderState {
/**
* 待支付状态
*
* @param context
*/ public abstract void unpay(OrderContext context);
/**
* 待发货状态
*
* @param context
*/ public abstract void undelivered(OrderContext context);
/**
* 已发货状态
*
* @param context
*/ public abstract void delivered(OrderContext context);
/**
* 已收货状态
*
* @param context
*/ public abstract void received(OrderContext context);
}
3、实现类定义
/**
* @Description: 具体订单状态角色:待支付状态
**/ public class UnpayState extends OrderState {
@Override
public void unpay(OrderContext context) {
System.out.println("订单待支付状态");
context.setState(new UndeliveredState());
}
@Override
public void undelivered(OrderContext context) {
System.out.println("订单待支付状态,请先支付");
}
@Override
public void delivered(OrderContext context) {
System.out.println("订单待支付状态,请先支付");
}
@Override
public void received(OrderContext context) {
System.out.println("订单待支付状态,请先支付");
}
}
/**
* @Description: 具体订单状态角色:待发货状态类
**/ public class UndeliveredState extends OrderState {
@Override
public void unpay(OrderContext context) {
System.out.println("订单已支付,请不要重复支付");
}
@Override
public void undelivered(OrderContext context) {
System.out.println("订单已支付等待发货啦");
context.setState(new DeliveredState());
}
@Override
public void delivered(OrderContext context) {
System.out.println("订单待发货,请先发货");
}
@Override
public void received(OrderContext context) {
System.out.println("订单待发货,请先发货");
}
}
/**
* @Description: 具体订单状态角色:已发货状态类
**/ public class DeliveredState extends OrderState {
@Override
public void unpay(OrderContext context) {
System.out.println("订单已支付,请不要重复支付");
}
@Override
public void undelivered(OrderContext context) {
System.out.println("订单已发货,请不要重复发货");
}
@Override
public void delivered(OrderContext context) {
System.out.println("订单已发货啦");
context.setState(new ReceivedState());
}
@Override
public void received(OrderContext context) {
System.out.println("订单已发货,未收到");
}
}
/**
* @Description: 具体订单状态角色:已收货状态类
**/ public class ReceivedState extends OrderState {
@Override
public void unpay(OrderContext context) {
System.out.println("订单已支付,请不要重复支付");
}
@Override
public void undelivered(OrderContext context) {
System.out.println("订单已发货,请不要重复发货");
}
@Override
public void delivered(OrderContext context) {
System.out.println("订单已发货啦");
}
@Override
public void received(OrderContext context) {
System.out.println("订单已收货啦");
}
}
4、上下文类定义
/**
* @Description: 环境角色:订单上下文类
**/ public class OrderContext {
// 抽象订单状态对象
private OrderState state;
public void setState(OrderState state) {
this.state = state;
}
/**
* 订单待支付状态
*/ public void unpay() {
state.unpay(this);
}
/**
* 订单待发货状态
*/ public void undelivered() {
state.undelivered(this);
}
/**
* 订单已发货状态
*/ public void delivered() {
state.delivered(this);
}
/**
* 订单已收货状态
*/ public void received() {
state.received(this);
}
}
5、测试
/**
* @Description: 状态模式客户端测试类
**/ public class Client {
public static void main(String[] args) {
OrderContext context = new OrderContext();
// 1.订单待支付状态
context.setState(new UnpayState());
context.unpay();
// 2.订单待发货状态
context.setState(new UndeliveredState());
context.undelivered();
// 3.订单已发货状态
context.setState(new DeliveredState());
context.delivered();
// 3.订单已收货状态
context.setState(new ReceivedState());
context.received();
}
}
控制台日志:
订单待支付状态
订单已支付等待发货啦
订单已发货啦
订单已收货啦