Bootstrap

【设计模式-观察者模式】

定义

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(被观察者)的状态变化当主题状态发生变化时,所有依赖于它的观察者都会收到通知并自动更新

UML图

在这里插入图片描述

  • Subject(主题/被观察者):定义了可以注册、注销观察者的方法,以及通知观察者的逻辑。
  • Observer(观察者):定义了一个更新接口,当被观察者状态发生变化时,观察者会通过该接口更新自己。
  • ConcreteSubject(具体主题):实现主题接口,维护观察者的列表,并在状态变化时通知观察者。
  • ConcreteObserver(具体观察者):实现观察者接口,定义在主题状态变化时的具体行为。

工作流程

  1. 观察者通过主题对象注册自己,以便接收更新。
  2. 主题对象在状态变化时调用观察者的更新方法。
  3. 观察者根据主题的最新状态进行相应的更新操作。

代码

import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    void update(String message);
}

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体主题类
class NewsAgency implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String news;

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

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

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(news);
        }
    }

    public void setNews(String news) {
        this.news = news;
        notifyObservers(); // 状态变化时通知所有观察者
    }
}

// 具体观察者类
class NewsChannel implements Observer {
    private String name;

    public NewsChannel(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received news update: " + message);
    }
}

// 测试观察者模式
public class ObserverPatternDemo {
    public static void main(String[] args) {
        NewsAgency newsAgency = new NewsAgency();
        
        NewsChannel channel1 = new NewsChannel("Channel 1");
        NewsChannel channel2 = new NewsChannel("Channel 2");

        newsAgency.registerObserver(channel1);
        newsAgency.registerObserver(channel2);

        newsAgency.setNews("Breaking News: Observer Pattern Explained!");
        newsAgency.setNews("More News: Observer Pattern in Action!");
    }
}

优点

  • 解耦:观察者和主题之间的耦合度低,主题不需要了解观察者的具体实现。
  • 动态添加观察者:可以在运行时动态地添加和移除观察者,灵活性高。
  • 广播机制:一个主题可以有多个观察者,状态变化时可以一并通知所有观察者。

缺点

  • 可能导致内存泄漏:如果观察者没有被正确注销,可能会造成内存泄漏。
  • 通知顺序不确定:多个观察者的更新顺序不固定,可能会导致状态不一致。
  • 复杂性增加:在复杂系统中,观察者和主题之间的关系可能变得难以管理和调试。

适用场景

  • 事件处理系统:如 GUI 事件监听,用户操作触发相应的事件。
  • 发布/订阅系统:如消息队列、社交媒体的通知系统等。
  • 数据变化监测:如实时数据监控、股票价格更新等。
;