设计模式-观察者模式

什么是观察者模式?

观察者模式是一种行为模式。
它定义了对象之间一对多的关系,其中如果一个对象改变了状态,所有依赖它的对象都会自动被通知并更新。
其中,有两个主要的角色被观察者(主题,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的实现方式,这里不细说了。
观察者模式的优劣
优点:满足了解耦的需求,上下游之间的强耦合关系通过此模式解决;
缺点:观察者模式是一种轻量的通信机制,且消息可靠性不高。调用场景过高的场景不应该使用观察者模式。
适用场景
基于优缺点,观察者模式在不要求消息高可靠性,以及调用次数较少的情况下可以使用。
如果是对于性能要求以及消息可靠性较高的情况下,建议使用消息队列,毕竟消息队列本身就是解决了类似的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值