状态模式(State)是一种行为型设计模式。当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。简单来说就是,一个含有多种状态的实例,其行为随状态的变化而变化。
电商购物时,订单的状态有非常多,如果单纯的通过if-else进行状态的判断后,进行后续操作,则代码的可维护性不高。此时可以通过状态模式,将订单的各个状态进行抽象。具体的状态下的操作,可以封装到对应的状态类型,从而将复杂的if-else判断逻辑简单化。
描述
状态转移图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ag4EdRrU-1586312336192)(./images/状态转移图.png)]
代码实现
State.java
/**
* 状态接口,状态的变化对应其中某一个接口
*/
public interface State {
/**
* 付款
*/
void payment() throws Exception;
/**
* 取消订单
*/
void cancel() throws Exception;
/**
* 发货
*/
void ship() throws Exception;
/**
* 收货
*/
void receipt() throws Exception;
/**
* 评价
*/
void evaluate() throws Exception;
/**
* 获取当前状态描述
*/
String getCurrentState();
}
AbstractState.java
/**
* 抽象状态类,起到适配作用
*/
public abstract class AbstractState implements State {
protected Order order;
public AbstractState(Order order) {
this.order = order;
}
@Override
public void payment() throws Exception {
System.out.println(order.getCurrentState() + "无法进行付款操作,请先提交订单");
throw new Exception();
}
@Override
public void cancel() throws Exception {
System.out.println(order.getCurrentState() + "无法进行取消操作");
throw new Exception();
}
@Override
public void ship() throws Exception {
System.out.println(order.getCurrentState() + "无法进行发货操作,请先付款");
throw new Exception();
}
@Override
public void receipt() throws Exception {
System.out.println(order.getCurrentState() + "无法进行收获操作,请先发货");
throw new Exception();
}
@Override
public void evaluate() throws Exception {
System.out.println(order.getCurrentState() + "无法进行评价操作,请先确认收获");
throw new Exception();
}
}
PendingPaymentState.java
/**
* 待付款状态类,此时可以对订单进行取消和付款
*/
public class PendingPaymentState extends AbstractState {
public PendingPaymentState(Order order) {
super(order);
}
/**
* 订单付款后,状态转为代发货
*/
@Override
public void payment() throws Exception {
order.setState(new ToBeDeliveredState(order));
}
/**
* 取消订单后,状态转为已完结
*/
@Override
public void cancel() throws Exception {
order.setState(new FinishedState(order));
}
@Override
public String getCurrentState() {
return StateEnum.PENDING_PAYMENT.getDesc();
}
}
ToBeDeliveredState.java
/**
* 待发货状态,订单在该状态下只能进行发货操作
*/
public class ToBeDeliveredState extends AbstractState {
public ToBeDeliveredState(Order order) {
super(order);
}
/**
* 订单进行发货操作,状态转为待收货
*/
@Override
public void ship() throws Exception {
order.setState(new ToBeReceivedState(order));
}
@Override
public String getCurrentState() {
return StateEnum.TO_BE_DELIVERED.getDesc();
}
}
ToBeReceivedState.java
/**
* 待收货状态,该状态只能进行收货操作
*/
public class ToBeReceivedState extends AbstractState {
public ToBeReceivedState(Order order) {
super(order);
}
/**
* 待收货状态,进行收货操作后状态变为待评价
*/
@Override
public void receipt() throws Exception {
order.setState(new CommentState(order));
}
@Override
public String getCurrentState() {
return StateEnum.TO_BE_RECEIVED.getDesc();
}
}
CommentState.java
/**
* 待评价状态,订单在该状态下只能进行评价操作
*/
public class CommentState extends AbstractState {
public CommentState(Order order) {
super(order);
}
/**
* 待评价状态下的订单,进行评价后,状态转为完结
*/
@Override
public void evaluate() throws Exception {
order.setState(new FinishedState(order));
}
@Override
public String getCurrentState() {
return StateEnum.COMMENT.getDesc();
}
}
FinishedState.java
/**
* 订单完结状态,订单无法进行任何操作
*/
public class FinishedState extends AbstractState {
public FinishedState(Order order) {
super(order);
}
@Override
public String getCurrentState() {
return StateEnum.FINISHED.getDesc();
}
}
Order.java
/**
* 订单
*/
public class Order {
/**
* 当前订单状态
*/
private State state;
/**
* 订单初始化状态为待付款
*/
public Order() {
this.state = new PendingPaymentState(this);
}
// 订单付款操作
public void payment() throws Exception {
state.payment();
}
// 订单取消操作
public void cancel() throws Exception {
state.cancel();
}
// 订单发货操作
public void ship() throws Exception {
state.ship();
}
// 订单收获操作
public void receipt() throws Exception {
state.receipt();
}
// 订单评价操作
public void evaluate() throws Exception {
state.evaluate();
}
// 查看订单当前状态
public String getCurrentState() {
return state.getCurrentState();
}
// 省略Getter和Setter方法
}
StateEnum.java
/**
* 订单状态枚举
*/
public enum StateEnum {
/**
* 待付款状态
*/
PENDING_PAYMENT(1, "待付款状态"),
TO_BE_DELIVERED(2, "待发货状态"),
TO_BE_RECEIVED(3, "待收货状态"),
COMMENT(1, "待评价状态"),
FINISHED(1, "已完结状态");
/**
* 状态对应code码
*/
private Integer stateCode;
/**
* 状态对应的描述
*/
private String desc;
StateEnum(Integer stateCode, String desc) {
this.stateCode = stateCode;
this.desc = desc;
}
public Integer getStateCode() {
return stateCode;
}
public String getDesc() {
return desc;
}
}
Client.java
/**
* 客户端
*/
public class Client {
public static void main(String[] args) throws Exception {
// 1. 创建订单,并查看订单状态
Order order = new Order();
// 1.1 输出:待付款状态
System.out.println(order.getCurrentState());
// 2. 进行付款操作
order.payment();
// 2.1 输出:待发货状态
System.out.println(order.getCurrentState());
// 2.2 跳过发货操作,直接进行评价操作,输出:待发货状态无法进行评价操作,请先确认收获
// order.evaluate();
// 3. 进行发货操作
// 3.1 输出:待收货状态
order.ship();
System.out.println(order.getCurrentState());
// 4. 确认收获
// 4.1 输出:待评价状态
order.receipt();
System.out.println(order.getCurrentState());
// 5. 订单评价
order.evaluate();
// 5.1 输出:已完结状态
System.out.println(order.getCurrentState());
}
}
略