大家好,我是老三,在项目里,经常会有一些主线业务之外的其它业务,比如,下单之后,发送通知、监控埋点、记录日志……
这些非核心业务,如果全部一梭子写下去,有两个问题,一个是业务耦合,一个是串行耗时。
下单之后的逻辑
所以,一般在开发的时候,都会把这些操作å抽象成观察者模式,也就是发布/订阅模式(这里就不讨论观察者模式和发布/订阅模式的不同),而且一般会采用多线程的方式来异步执行这些观察者方法。
观察者模式
一开始,我们都是自己去写观察者模式。
自己实现观察者模式
观察者简图
观察者
-
观察者定义接口
/**
* @Author: fighter3
* @Description: 观察者接口
* @Date: 2022/11/7 11:40 下午
*/
public interface OrderObserver {
void afterPlaceOrder(PlaceOrderMessage placeOrderMessage);
}
- 具体观察者@Slf4j
public class OrderMetricsObserver implements OrderObserver {
@Override
public void afterPlaceOrder(PlaceOrderMessage placeOrderMessage) {
log.info("[afterPlaceOrder] metrics");
}}@Slf4j
public class OrderLogObserver implements OrderObserver{
@Override
public void afterPlaceOrder(PlaceOrderMessage placeOrderMessage) {
log.info("[afterPlaceOrder] log.");
}}@Slf4j
public class OrderNotifyObserver implements OrderObserver{
@Override
public void afterPlaceOrder(PlaceOrderMessage placeOrderMessage) {
log.info("[afterPlaceOrder] notify.");
}}- 业务通知观察者
- 日志记录观察者
- 监控埋点观察者
被观察者
- 消息实体定义
@Data
public class PlaceOrderMessage implements Serializable {
/**
* 订单号
*/
private String orderId;
/**
* 订单状态
*/
private Integer orderStatus;
/**
* 下单用户ID
*/
private String userId;
//……
}
- 被观察者抽象类
public abstract class OrderSubject {
//定义一个观察者列表
private List<OrderObserver> orderObserverList = new ArrayList<>();
//定义一个线程池,这里参数随便写的
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 12, 6, TimeUnit.SECONDS, new ArrayBlockingQueue<>(30));
//增加一个观察者
public void addObserver(OrderObserver o) {
this.orderObserverList.add(o);
}
//删除一个观察者
public void delObserver(OrderObserver o) {
this.orderObserverList.remove(o);
}
//通知所有观察者
public void notifyObservers(PlaceOrderMessage placeOrderMessage) {
for (OrderObserver orderObserver : orderObserverList) {
//利用多线程异步执行
threadPoolExecutor.execute(() -> {
orderObserver.afterPlaceOrder(placeOrderMessage);
});
}
}
}
这里利用了多线程,来异步执行观察者。
- 被观察者实现类
/**
* @Author: fighter3
* @Description: 订单实现类-被观察者实现类
* @Date: 2022/11/7 11:52 下午
*/
@Service
@Slf4j
public class OrderServiceImpl extends OrderSubject implements OrderService {
/**
* 下单
*/
@Override
public PlaceOrderResVO placeOrder(PlaceOrderReqVO reqVO) {