设计模式之观察者模式

前言

本篇主要介绍spring封装后的观察者模式的实际应用,在写作的过程中作者会尽量控制篇幅,有任何有问题的地方请帮忙指出,谢谢。

需求

电商项目中,用户购买商品(订单支付成功)后,同时还得给用户加积分、写流水和其他操作。

接下来会用观察者模式实现该业务。

观察者模式

1.定义

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

MQ就是标准按照观察者模式设计的中间件。

2.优缺点

优点:

  1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
  2. 目标与观察者之间建立了一套触发机制。

缺点:

  1. 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  2. 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

3.spring观察者结构

  1. Event 事件,相当于是消息体。
  2. Listener 监听者,观察者角色,相当于是消息消费者。
  3. Publisher 发送者,被观察者角色,相当于消息生产者。

非常类似于MQ。

4.应用场景

  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  3. 实现类似广播机制的功能,不需要知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。
  4. 多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。

设计模式实现

1.Event 事件

/**
 *  Event事件
 * @author winter
 */
@Component
public class OrderEvent extends ApplicationEvent {

    public OrderEvent(ApplicationContext source) {
        super(source);
    }

    public String getOrderId() {
        return "o1234";
    }
}

2.Listener 监听者

/**
 *  Listener监听者 处理积分
 * @author winter
 */
@Component
public class IntegralListener implements ApplicationListener<OrderEvent> {

    @Override
    public void onApplicationEvent(OrderEvent orderEvent) {
        String message = orderEvent.getOrderId();
        System.out.println("用户支付订单:"+message+"成功,用户积分+1");
    }
}
/**
 *  Listener监听者 处理账号的流水
 * @author winter
 */
@Component
public class AccountListener implements ApplicationListener<OrderEvent> {

    @Override
    public void onApplicationEvent(OrderEvent orderEvent) {
        String message = orderEvent.getOrderId();
        System.out.println("用户支付订单:"+message+"成功,添加用户流水");
    }
}

3.Listener 监听者

/**
 * 订单创建的发送者
 * @author winter
 */
@Component
public class OrderPublisher implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 发布事件
     * 监听该事件的监听者都可以获取消息
     *
     * @param orderEvent
     */
    public void publisherEvent(OrderEvent orderEvent) {
        //订单下发成功
        System.out.println("订单:"+ orderEvent.getOrderId()+"支付成功。。。");
        applicationContext.publishEvent(orderEvent);
    }
}

4.测试

@SpringBootTest
class ObserveApplicationTests {
    @Autowired
    private OrderPublisher orderPublisher;
    @Autowired
    private OrderEvent orderEvent;
    @Test
    void contextLoads() {
        orderPublisher.publisherEvent(orderEvent);
    }

}

测试结果:
订单:o1234支付成功。。。
用户支付订单:o1234成功,添加用户流水
用户支付订单:o1234成功,用户积分+1

总结

类似的业务场景还是推荐使用MQ,如果受资源限制还是可以使用观察者模式来设计业务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值