什么是观察者模式?
观察者模式是一种行为模式。
它定义了对象之间一对多的关系,其中如果一个对象改变了状态,所有依赖它的对象都会自动被通知并更新。
其中,有两个主要的角色被观察者(主题,Subject)和观察者(Observer)。
其中,被观察者会维护一个观察者列表,并提供了注册、删除等的维护方法,当被观察者发生改变时,通知观察者做出对应的改变。
观察者模式的核心思想:将主题和观察者解耦,使得主题的变化和观察者的响应操作解耦,而无需主题变化时轮询调用观察者的更新方法。
实际场景解读
我们以优惠劵场景为例,
假定我们有个优惠券业务,初始状态为禁用,当状态变更为启用后,我们需要更新与之相关的一些数据(比如店铺需要打上有可领取的优惠券标记,比如优惠券关联的商品需要进行可用优惠券标记等等)
我们先自己实现一下:
//优惠券主题
public interface CouponStatusSubject{
//观察者注册
void registerObserver(Observer observer);
//观察者移除
void removeObserver(Observer observer);
//观察者唤醒
void notifyObserver();
}
//优惠券主题实现
public class CouponStatusSubject implements CouponStatusSubject{
private List<Observer> observers;
private Coupon coupon;
public String getCoupon () {
return name;
}
public void setCoupon (Coupon coupon) {
this.coupon= coupon;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
}
@Override
public void removeObserver(Observer observer) {
}
//唤醒观察者,并执行相关方法
@Override
public void notifyObservers() {
for(Observer observer:observers){
observer.linkageUpdate(this.coupon);
}
}
}
/**
* 观察者接口类
*/
public interface Observer {
void linkageUpdate(Coupon coupon);
}
//商品继承观察者,实现联动修改方法
class ProductService implements Observer{
void linkageUpdate(Coupon coupon);
}
//店铺继承观察者,实现联动修改方法
class ShopService implements Observer{
void linkageUpdate(Coupon coupon);
}
//其他继承观察者,实现联动修改方法
class OtherService implements Observer{
void linkageUpdate(Coupon coupon);
}
那么如何调用呢
public static void main(){
CouponStatusSubject couponStatusSubject=new CouponStatusSubject();
ProductService productService=new ProductService();
ShopService shopService=new ShopService();
couponStatusSubject.registerObserver(productService);
couponStatusSubject.registerObserver(shopService);
Coupon coupon=new Coupon();
couponStatusSubject.setCoupon(coupon);
}
这就是一种最基本的观察者模式的自定义实现方式。
spring实现观察者模式
/**
* 基于spring实现观察者模式
* 消息对象定义
*/
public class CustEvent extends ApplicationEvent {
public String msg;
public CustEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
/**
* 生产者
*/
public class EventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher=applicationEventPublisher;
}
public void publish(String message){
publisher.publishEvent(new CustEvent( this, message));
}
/**
* 消费者
*/
@Component
public class CustEventListener {
@EventListener()
public void eventListen(CustEvent custEvent){
//消费逻辑
}
测试
public class test {
@Resource
EventPublisher eventPublisher;
public void event(String str) {
eventPublisher.publish("hello");
}
此外,还有一种实现方式是基于Java原生接口
实现java.util.Observer的实现方式,这里不细说了。
观察者模式的优劣
优点:满足了解耦的需求,上下游之间的强耦合关系通过此模式解决;
缺点:观察者模式是一种轻量的通信机制,且消息可靠性不高。调用场景过高的场景不应该使用观察者模式。
适用场景
基于优缺点,观察者模式在不要求消息高可靠性,以及调用次数较少的情况下可以使用。
如果是对于性能要求以及消息可靠性较高的情况下,建议使用消息队列,毕竟消息队列本身就是解决了类似的问题。