目录
应用场景
订单状态和操作
| 订单状态 | 当前订单状态下,可以执行的操作 |
|---|---|
| 新生成、未提交 | 提交订单、修改订单、取消订单 |
| 已提交 | 支付订单、修改订单、取消订单 |
| 已支付 | 确认订单、修改订单、取消订单 |
| 已确认 | 商品出库 |
| 运输中 | 买家收货、买家拒收 |
| 未评价 | 评价 |
| 订单完成 | 再来一单 |
上面以订单状态的管理作为引子来分析【状态模式】在项目中的使用,只作为思维上的启发和演示。实际项目中具体情况具体分析。
难点分析
如上图所示,订单状态比较多,在某个状态下都有对应的可以执行的操作,除此之外的其他操作是不允许的,在写接口时我们需要判断和拦截非法操作,确保安全。而执行允许的操作又可能造成订单状态的改变。
解决方案之状态模式
针对上述场景,可能很多人想着用很多嵌套的 if 来判断。状态之多和变化,会使得判断逻辑很复杂,易出bug且扩展性很差。
下面讲述一下,使用【状态模式】来解决类似场景。
类图

OrderState接口
- 顾名思义 "订单状态",里面定义了对订单的所有操作。
- 由于每一个操作都可能造成当前订单状态的变化,所以操作的返回值是新的订单状态,如果操作没有造成订单状态的改变(比如说:修改操作),那么可以直接返回当前状态(this)
/**
* 订单状态接口,里面定义了对订单的所有操作
*
* @author passerbyYSQ
* @create 2021-06-06 11:00
*/
public interface OrderState {
// 提交订单
OrderState submit();
// 更新订单信息
OrderState update();
// 支付订单
OrderState pay();
// 确认订单之前均可取消
OrderState cancel();
// 确认核对订单信息
OrderState confirm();
// 出库
OrderState deliver();
// 收货
OrderState receive();
// 拒收
OrderState refuse();
// 评价
OrderState evaluate();
// 再来一单
OrderState reBuy();
}
AstractOrderState抽象类
- 增加一个状态描述属性,描述当前状态
- 实现 OrderState 接口,给所有操作作默认实现:不支持当前操作(拦截非法操作),并返回当前的订单状态(this)
/**
* @author passerbyYSQ
* @create 2021-06-06 11:17
*/
public class AbstractOrderState implements OrderState {
private String desc; // 状态描述
public AbstractOrderState(String desc) {
this.desc = desc;
}
@Override
public OrderState submit() {
System.out.println("当前状态为:" + desc + ",不支持提交操作");
return this;
}
@Override
public OrderState update() {
System.out.println("当前状态为:" + desc + ",不支持修改操作");
return this;
}
@Override
public OrderState pay() {
System.out.println("当前状态为:" + desc + ",不支持支付操作");
return this;
}
@Override
public OrderState cancel() {
System.out.println("当前状态为:" + desc + ",不支持取消操作");
return this;
}
@Override
public OrderState confirm() {
System.out.println("当前状态为:" + desc + ",不支持确认操作");
return this;
}
@Override
public OrderState deliver() {
System.out.println("当前状态为:" + desc + ",不支持出库操作");
return this;
}
@Override
public OrderState receive() {
System.out.println("当前状态为:" + desc + ",不支持收货操作");
return this;
}
@Override
public OrderState refuse() {
System.out.println("当前状态为:" + desc + ",不支持拒收操作");
return this;
}
@Override
public OrderState evaluate() {
System.out.println("当前状态为:" + desc + ",不支持评价操作");
return this;
}
@Override
public OrderState reBuy() {
System.out.println("当前状态为:" + desc + ",不支持再购操作");
return this;
}
@Override
public String toString() {
return desc;
}
}
具体的状态实现类举例
Submitted 已提交状态
/**
* @author passerbyYSQ
* @create 2021-06-06 11:27
*/
public class Submitted extends AbstractOrderState {
public Submitted() {
super("已提交");
}
@Override
public OrderState update() {
System.out.println("修改订单完成");
return this;
}
@Override
public OrderState pay() {
System.out.println("支付订单完成");
return new Paid(); // 订单状态改变!!!--> 已支付状态
}
@Override
public OrderState cancel() {
System.out.println("取消订单完成");
return new Cancelled(); // 订单状态改变!!!--> 取消状态
}
}
Completed 已完成状态
/**
* @author passerbyYSQ
* @create 2021-06-06 12:00
*/
public class Completed extends AbstractOrderState {
public Completed() {
super("已完成");
}
@Override
public OrderState reBuy() {
System.out.println("再来一单");
return new NotSubmitted();
}
}
Order 订单类
- 订单里面持有一个订单状态类
- 订单实现了 OrderState 接口,并实现了全部方法,但是具体的实现 (判断、业务逻辑、状态改变) Order 类本身并不负责,而是委托给了 "当前的订单状态类实例"
/**
* @author passerbyYSQ
* @create 2021-06-06 12:06
*/
public class Order implements OrderState {
private OrderState state;
public Order(OrderState state) {
this.state = state;
}
@Override
public OrderState submit() {
return state = state.submit();
}
@Override
public OrderState update() {
return state = state.update();
}
@Override
public OrderState pay() {
return state = state.pay();
}
@Override
public OrderState cancel() {
return state = state.cancel();
}
@Override
public OrderState confirm() {
return state = state.confirm();
}
@Override
public OrderState deliver() {
return state = state.deliver();
}
@Override
public OrderState receive() {
return state = state.receive();
}
@Override
public OrderState refuse() {
return state = state.refuse();
}
@Override
public OrderState evaluate() {
return state = state.evaluate();
}
@Override
public OrderState reBuy() {
return state = state.reBuy();
}
public OrderState getState() {
return state;
}
}
测试和使用
/**
* @author passerbyYSQ
* @create 2021-06-06 12:06
*/
public class TestMain {
public static void main(String[] args) {
Order order = new Order(new NotSubmitted());
order.update();
order.pay(); // 失败。当前订单处于"未提交"状态,不允许支付
order.confirm(); // 失败。
order.submit(); // 提交订单。状态变为"已提交"
order.pay(); // 支付订单。状态变为"已支付"
order.receive(); // 失败。当前状态为"已支付",不允许买家收货
order.cancel();
System.out.println(order.getState());
}
}
本文介绍了一种利用状态模式处理订单状态转换的方法,通过定义订单状态接口和抽象类,实现了不同订单状态下的合法操作及状态变迁。
1388

被折叠的 条评论
为什么被折叠?



