贯穿设计模式-状态模式+观察者模式

118 阅读2分钟

代码

样例所有代码可以github.com/WeiXiao-Hyy…获取

PS:一开始画图的时候用的PPT,但是感觉还是应该专业一点,还是换成了staruml,果然用起来顺手多了。

需求

电商的订单有很多状态如:订单初始化(OrderCreate),订单未付款(OrderWaitPay),订单未发货(OrderWaitSend),等待发货(OrderWaitReceive),订单收到已确认(OrderFinish)等等

其中状态的转化可以使用状态模式来进行设计,同时状态的转化需要作出对应的操作,比如订单付款之后需要使用异步消息通知店家系统进行发货等等,则需要使用到观察者模式

状态模式-有状态实现

状态模式-有状态.png

//此处Component有问题,会导致只能创建一个订单,因此将Context转化为一个无状态的类
@Component
public class DeprecatedOrderContext {

    //引入抽象状态,用于状态方法的调用
    @Setter
    private DeprecatedAbstractOrderState currentStatus;
    ......
}

但是这里有一个问题,如果在Context中保存了抽象的状态类(是一个有状态的Context),那么只能支持一个订单状态的转化(因为在状态转化中currentState需要保存当前的订单状态,但在多并发的场景下不能只用一个Context,应该为一个订单一个Context)为了解决以上问题引入了无状态的Context。

状态模式-无状态

状态模式-无状态.png

@Component
public class DeprecatedOrderContext {
    @Autowired
    private DeprecatedCreateOrder deprecatedCreateOrder;

    @Autowired
    private DeprecatedPayOrder deprecatedPayOrder;

    @Autowired
    private DeprecatedSendOrder deprecatedSendOrder;

    @Autowired
    private DeprecatedReceiveOrder deprecatedReceiveOrder;
    ......
}

观察者模式

Subject为被观察者,则为DeprecatedAbstractOrderState类 +subject:代表着关联关系,在Subject中关联观察者

观察者模式.png

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);
        }
    }
}

参考书籍

《贯穿设计模式-用一个电商项目详解设计模式》