设计者模式之观察者模式

模式描述

角色

  • 抽象主题(Subject)角色:它是一个抽象类或接口,提供了添加、删除观察者的方法,与通知观察者进行变更的方法
  • 具体主题(Concrete Subject)角色:具体实现类
  • 抽象观察者(Observer)角色:它是一个抽象类或接口,提供了观察者变更的方法
  • 具体观察者(Concrete Observer)角色:具体实现类

特征

  • 针对一对多模式下的松耦合
  • 做到及时通讯效果(目标与观察者之间建立了一套触发机制)
  • 观察者多的情况下,及时通讯效率会有所下降。观察者会被放到 Collection 集合中。

场景

多用于单一应用下的系统逻辑,在 Spring 源码中就用到观察者模式。对于跨系统间通讯不适合。

模式实现

1、被观察者

/*
 * 被观察者,
 * 我作为 微信公众号,允许用户进行订阅与取消订阅
 * 同时,我可以为订阅者,推送消息
 */
public interface Subject {

    // 添加订阅关系
    void attach(Observer observer);
    // 移除订阅关系
    void detach(Observer observer);
    // 通知订阅者
    void notifyObservers(String message);

}

2、具体被观察者

public class ConcreteSubject implements Subject{

    // 订阅者容器(list、map 都可以)
    private List<Observer> observers = new ArrayList<Observer>();

    @Override
    public void attach(Observer observer) {
        // 添加订阅关系
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        // 移除订阅关系
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        // 通知订阅者
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

3、观察者

/**
 * 观察者模式
 * 我作为微信用户,会实时获取到微信公众号推送的各种消息

 */
public interface Observer {

    //更新方法
    public void update(String message);

}

4、具体观察者

public class ConcreteObserver implements Observer{

    @Override
    public void update(String message) {
        // 模拟处理业务逻辑
        System.out.println("用户收到消息:" + message);
    }
}

5、测试

public class Client {

    public static void main(String[] args) {

        ConcreteSubject subject = new ConcreteSubject();
        // 这里假设是增加新用户
        subject.attach(new ConcreteObserver());
        ConcreteObserver twoObserver = new ConcreteObserver();
        subject.attach(twoObserver);

        // 发送朋友圈动态
        subject.notifyObservers("第一条消息");

        subject.detach(twoObserver);

        subject.notifyObservers("第二个消息");
    }
}

运行结果
用户收到消息:第一条消息
用户收到消息:第一条消息

用户收到消息:第二个消息

Spring 源码中的应用

观察者模式 与 发布订阅模式

关注点:

  1. 推送是 主动的。
  2. 渠道可以是多个,发布者发布多个,订阅者订阅多个。
  3. 发布订阅模式,可以认为包含观察者模式。subject <==> channel
posted @ 2022-04-07 16:28  之士咖啡  阅读(34)  评论(0编辑  收藏  举报