设计模式-观察者模式

2,545 阅读4分钟

# 七大软件设计原则
# 设计模式-工厂模式
# 设计模式-单例模式
# 设计模式-原型模式
# 设计模式-策略模式
# 设计模式-责任链模式
# 设计模式-建造者模式
# 设计模式-深度分析代理模式
# 设计模式-门面模式
# 设计模式-装饰器模式
# 设计模式-享元模式
# 设计模式-组合模式
# 设计模式-适配器模式
# 设计模式-桥接模式
# 设计模式-委派模式
# 设计模式-模板方法模式
# 设计模式-迭代器模式
# 设计模式-命令模式
# 设计模式-备忘录模式
# 设计模式-状态模式
# 设计模式-中介者模式
# 设计模式-解释器模式

观察者模式(Observer Pattern),又叫发布-订阅(Publish/Subscribe)模式、模型-视图 Model/View ) 模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。定义一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听,使得每当主题对象状态变化时,所 有依赖于它的对象都会得到通知并被自动更新。属于行为型模式。

观察者模式的核心是将观察者与被观察者解耦,以类似于消息/广播发送的机制联动两者,使被观察 者的变动能通知到感兴趣的观察者们,从而做出相应的响应。比如我们项目中常用的MQ、异步队列。

适用场景

这个模式我们使用的就比较多了,比如消息分发平时我们修改一个系统的东西的时候可能需要牵扯到多个系统同时修改,这个时候我们就可以使用观察者模式。总结一下以下几点适合使用该模式:

  1. 当—个抽象模型包含两个方面内容,其中一个方面依赖于另一个方面;
  2. 其他一个或多个对象的变化依赖于另一个对象的变化;
  3. 实现类似广播机制的功能,无需知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播;
  4. 多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。

UML类图

image.png 具体代码如下: 首先是被观察者它主要的功能是:

  1. 一个目标可以被多个观察者观察
  2. 目标提供对观察者注册和退订的维护
  3. 当目标的状态发生变化时,目标负责通知所有注册的、有效的观察者

ISubject它的主要作用就是定义接口(主要是订阅和取消订阅以及通知的接口)

public interface ISubject {
    void attach(IObserver observer);
    void detach(IObserver observer);
    void notifyObservers();
}

然后是具体的被观察对象ConcreteSubject这里主要实现具体方法

public class ConcreteSubject implements ISubject{

    private static final List<IObserver> observers = new ArrayList<>();

    @Override
    public void attach(IObserver observer) {
        observers.add(observer);
    }

    @Override
    public void detach(IObserver observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (IObserver observer : observers) {
            observer.update();
        }
    }
}

然后就是观察者,观察者的功能就比较少了就是实现方法等待被通知

public interface IObserver {
    void update();
}
public class ConcreteObserver implements IObserver{
    @Override
    public void update() {
        System.out.println("被观察者更新了数据");
    }
}

最后再看一下客户端的使用:

public class Client {
    public static void main(String[] args) {
        ISubject subject = new ConcreteSubject();
        IObserver observer = new ConcreteObserver();
        subject.attach(observer);
        subject.notifyObservers();
    }
}

image.png

观察者模式的优缺点

优点:

  1. 观察者和被观察者是松耦合(抽象耦合)的,符合依赖倒置原则
  2. 分离了表示层(观察者) 和数据逻辑层(被观察者),并且建立了一套触发机制,使得数据的变 化可以响应到多个表示层上;
  3. 实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者触发事件时,只 有感兴趣的观察者可以接收到通知。

缺点:

  1. 如果观察者数量过多,则事件通知会耗时较长;
  2. 事件通知呈线性关系,如果其中一个观察者处理事件卡壳,会影响后续的观察者接收该事件;
  3. 如果观察者和被观察者之间存在循环依赖,则可能造成两者之间的循环调用,导致系统崩溃。