1、解决的问题
订单的状态变化,待支付、待发货、待签收、已取消、已完成,待支付和待发货状态下可以进行支付和取消两个动作。
正常写法:
String action = "payOrder";
OrderStateEnum state = OrderStateEnum.WaitPay;
if (OrderStateEnum.WaitPay.equals(state)) {
if ("payOrder".equals(action)) {
System.out.println("支付订单,修改成待发货状态");
state = OrderStateEnum.WaitDeliver;
}
if ("cancel".equals(action)) {
System.out.println("取消订单,修改成已取消");
state = OrderStateEnum.Cancel;
}
}
else if(OrderStateEnum.WaitDeliver.equals(state)) {
if ("deliverOrder".equals(action)) {
System.out.println("订单发货,修改成待签收状态");
state = OrderStateEnum.WaitSign;
}
if ("cancel".equals(action)) {
System.out.println("取消订单,修改成已取消");
state = OrderStateEnum.Cancel;
}
}
//其他判断的省略
System.out.println("最终的订单状态:" + state.getName());
这种写法如果进行状态的增加,代码会非常复杂,可读性差
2、使用状态模式:
public enum OrderStateEnum {
/**待支付*/
WaitPay("待支付"),
/**待发货*/
WaitDeliver("待发货"),
/**待签收*/
WaitSign("待签收"),
/**已完成*/
Finish("已完成"),
/**已取消*/
Cancel("已取消");
private String name;
OrderStateEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public abstract class OrderState {
private OrderStateContext context;
public void setContext(OrderStateContext context) {
this.context = context;
}
public OrderStateContext getContext() {
return context;
}
/**
* 支付订单
*/
public abstract void payOrder();
/**
* 订单发货
*/
public abstract void deliverOrder();
/**
* 用户确认收货
*/
public abstract void signOrder();
/**
* 取消订单
*/
public abstract void cancelOrder();
public abstract OrderStateEnum getCurrentState();
}
public class OrderStateContext {
//定义出所有的订单状态
public static OrderState waitPayState;
public static OrderState waitDeliverState;
public static OrderState waitSignState;
public static OrderState cancelState;
public static OrderState finishState;
public OrderStateContext(String orderId) {
waitPayState = new WaitPayState(orderId);
waitDeliverState = new WaitDeliverState(orderId);
waitSignState = new WaitSignState(orderId);
cancelState = new CancelState(orderId);
finishState = new FinishState(orderId);
}
/**
* 当前状态
*/
private OrderState state;
public OrderState getState() {
return state;
}
public void setState(OrderState state) {
this.state = state;
//把当前的环境通知到各个实现类中
this.state.setContext(this);
}
public void payOrder() {
this.state.payOrder();
}
public void deliverOrder() {
this.state.deliverOrder();
}
public void signOrder() {
this.state.signOrder();
}
public void cancelOrder() {
this.state.cancelOrder();
}
}
/**
* 在订单待发货的状态下能做什么事情
*/
public class WaitDeliverState extends OrderState {
private String orderId;
public WaitDeliverState(String orderId) {
this.orderId = orderId;
}
@Override
public void payOrder() {
}
@Override
public void deliverOrder() {
System.out.println("订单" + orderId + "发货");
this.getContext().setState(OrderStateContext.waitSignState);
}
@Override
public void signOrder() {
}
@Override
public void cancelOrder() {
//状态修改
this.getContext().setState(OrderStateContext.cancelState);
//动作委托为cancelState来执行,最终状态
this.getContext().getState().cancelOrder();
}
@Override
public OrderStateEnum getCurrentState() {
return OrderStateEnum.WaitDeliver;
}
}
/**
* 在订单未支付的状态下能做什么事情
*/
public class WaitPayState extends OrderState {
private String orderId;
public WaitPayState(String orderId) {
this.orderId = orderId;
}
@Override
public void payOrder() {
//变更状态前,要执行的事件,或者检查条件
System.out.println("支付" + orderId + "订单");
//状态修改
this.getContext().setState(OrderStateContext.waitDeliverState);
}
@Override
public void deliverOrder() {
}
@Override
public void signOrder() {
}
@Override
public void cancelOrder() {
//状态修改
this.getContext().setState(OrderStateContext.cancelState);
//动作委托为cancelState来执行,最终状态
this.getContext().getState().cancelOrder();
}
@Override
public OrderStateEnum getCurrentState() {
return OrderStateEnum.WaitPay;
}
}
public class CancelState extends OrderState {
private String orderId;
public CancelState(String orderId) {
this.orderId = orderId;
}
@Override
public void payOrder() {
}
@Override
public void deliverOrder() {
}
@Override
public void signOrder() {
}
@Override
public void cancelOrder() {
System.out.println("取消" + orderId + "订单");
}
@Override
public OrderStateEnum getCurrentState() {
return OrderStateEnum.Cancel;
}
}
3、运行效果
public static void main(String[] args) {
OrderStateContext context = new OrderStateContext("11132");
context.setState(OrderStateContext.waitPayState);//初始状态
context.payOrder();//订单支付
System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
context.deliverOrder();//发货
System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
context.cancelOrder();//取消订单
System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
}
支付11132订单
订单状态为:待发货
订单11132发货
订单状态为:待签收
取消11132订单
订单状态为:已取消