(行为型模式)观察者模式

126 阅读2分钟

前言

观察者模式定义了一种一对多的关系,其中一个对象(称为观察者)可以订阅另一个对象(称为主题)的更改,并在主题发生更改时自动接收通知。这样,观察者对象就可以根据主题的状态来更新自己的状态。这种模式可以让主题和观察者之间松耦合,从而使两者独立变化。

角色

  • 观察者:观察者是一个接口或抽象类,定义了一个更新自己的方法,当主题状态改变时,观察者需要实现这个方法来更新自己的状态。
  • 具体观察者:具体观察者是观察者的实现类,在具体观察者中实现更新自己的方法,以便在主题状态改变时更新自己的状态。
  • 主题:主题是一个接口或抽象类,定义了一些方法来管理观察者的生命周期,如注册、移除和通知观察者。
  • 具体主题:具体主题是主题的实现类,在具体主题中实现了主题的方法,以便管理。

代码示例

观察者

public interface Observer {
    void update(Subject subject);
}

具体观察者

public class ConcreteObserver implements Observer{

    private String name;

    public ConcreteObserver(String name){
        this.name = name;
    }
    @Override
    public void update(Subject subject) {
        //更新状态
        System.out.println(this.name + "收到通知");
    }

主题

public interface Subject {
    /**
     * 注册观察者
     * @param observer
     */
    void registerObserver(Observer observer);

    /**
     * 移除观察者
     * @param observer
     */
    void removeObserver(Observer observer);

    /**
     * 通知所有观察者
     */
    void notifyObservers();
}

具体主题

public class ConcreteSubject implements Subject{

    List<Observer> observers = new ArrayList<>();


    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

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

测试

public class Demo {

    public static void main(String[] args) {
        // 创建一个主题对象
        Subject subject = new ConcreteSubject();

        // 创建两个观察者对象
        Observer observer1 = new ConcreteObserver("观察者1号");
        Observer observer2 = new ConcreteObserver("观察者2号");

        // 将观察者注册到主题中
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        //发送通知
        subject.notifyObservers();

    }
}

输出

7M4c0cM0jy.jpg

优缺点

优点

  • 实现了观察者和被观察者之间的松耦合,观察者可以通过接口接收通知,而不用关心被观察者的实现细节。
  • 支持一个被观察者对象同时被多个观察者观察,并且支持观察者动态地添加和删除。

缺点

  • 当被观察者对象发生变化时,需要通知所有观察者,这可能会带来一定的性能问题,特别是在观察者数量比较多的情况下。
  • 如果观察者和被观察者之间的依赖关系过于紧密,观察者可能会变得臃肿,导致代码的复杂度和可维护性降低