代码
样例所有代码可以https://github.com/WeiXiao-Hyy/Design-Patterns获取
PS:一开始画图的时候用的PPT,但是感觉还是应该专业一点,还是换成了staruml,果然用起来顺手多了。
需求
电商的订单有很多状态如:订单初始化(OrderCreate),订单未付款(OrderWaitPay),订单未发货(OrderWaitSend),等待发货(OrderWaitReceive),订单收到已确认(OrderFinish)等等
其中状态的转化可以使用状态模式来进行设计,同时状态的转化需要作出对应的操作,比如订单付款之后需要使用异步消息通知店家系统进行发货等等,则需要使用到观察者模式。
状态模式-有状态实现
//此处Component有问题,会导致只能创建一个订单,因此将Context转化为一个无状态的类
@Component
public class DeprecatedOrderContext {
//引入抽象状态,用于状态方法的调用
@Setter
private DeprecatedAbstractOrderState currentStatus;
......
}
但是这里有一个问题,如果在Context中保存了抽象的状态类(是一个有状态的Context),那么只能支持一个订单状态的转化(因为在状态转化中currentState需要保存当前的订单状态,但在多并发的场景下不能只用一个Context,应该为一个订单一个Context)为了解决以上问题引入了无状态的Context。
状态模式-无状态
@Component
public class DeprecatedOrderContext {
@Autowired
private DeprecatedCreateOrder deprecatedCreateOrder;
@Autowired
private DeprecatedPayOrder deprecatedPayOrder;
@Autowired
private DeprecatedSendOrder deprecatedSendOrder;
@Autowired
private DeprecatedReceiveOrder deprecatedReceiveOrder;
......
}
观察者模式
Subject为被观察者,则为DeprecatedAbstractOrderState类
+subject:代表着关联关系,在Subject中关联观察者
public abstract class DeprecatedAbstractOrderState {
//在SpringBoot框架中无法优雅地将几个观察者注入到List中去
protected final List<DeprecatedAbstractObserver> observerList = new Vector<>();
public void addObserver(DeprecatedAbstractObserver observer) {
this.observerList.add(observer);
}
public void removeObserver(DeprecatedAbstractObserver observer) {
this.observerList.remove(observer);
}
public void notifyObserver(String orderId, String orderState) {
for (DeprecatedAbstractObserver observer : observerList) {
observer.orderStateHandler(orderId, orderState);
}
}
}