设计模式-观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。观察者模式常用于事件驱动的系统中,比如发布订阅系统、GUI 事件模型等。


观察者模式的关键角色:

  1. 主题(Subject)
    • 被观察的对象,维护一个观察者列表,提供添加、移除观察者的方法,并在自身状态发生变化时通知观察者。
  2. 观察者(Observer)
    • 接收通知并更新状态的对象。通常需要实现一个更新方法。
  3. 具体主题(ConcreteSubject)
    • 实现主题接口,保存具体状态,并在状态改变时通知观察者。
  4. 具体观察者(ConcreteObserver)
    • 实现观察者接口,定义具体的更新逻辑。

示例代码:天气预报系统

问题背景

假设有一个天气预报系统,当天气发生变化时,需要通知多个设备(手机、平板、显示屏等)。

实现代码

// 1. 抽象观察者接口
interface Observer {
    void update(String weather);
}

// 2. 抽象主题接口
interface Subject {
    void addObserver(Observer observer);    // 添加观察者
    void removeObserver(Observer observer); // 移除观察者
    void notifyObservers();                 // 通知所有观察者
}

// 3. 具体主题(WeatherStation)
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>(); // 保存观察者
    private String weather; // 天气状态

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

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

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(weather); // 通知每个观察者
        }
    }

    // 设置天气并通知观察者
    public void setWeather(String weather) {
        this.weather = weather;
        System.out.println("天气更新为: " + weather);
        notifyObservers();
    }
}

// 4. 具体观察者(手机)
class MobileDevice implements Observer {
    private String name;

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

    @Override
    public void update(String weather) {
        System.out.println(name + " 收到天气更新: " + weather);
    }
}

// 5. 具体观察者(显示屏)
class DisplayScreen implements Observer {
    @Override
    public void update(String weather) {
        System.out.println("显示屏更新天气: " + weather);
    }
}

// 6. 客户端
public class ObserverPatternExample {
    public static void main(String[] args) {
        // 创建主题
        WeatherStation weatherStation = new WeatherStation();

        // 创建观察者
        Observer mobile1 = new MobileDevice("手机A");
        Observer mobile2 = new MobileDevice("手机B");
        Observer display = new DisplayScreen();

        // 注册观察者
        weatherStation.addObserver(mobile1);
        weatherStation.addObserver(mobile2);
        weatherStation.addObserver(display);

        // 更新天气,通知观察者
        weatherStation.setWeather("晴天");
        weatherStation.setWeather("下雨");

        // 移除一个观察者
        weatherStation.removeObserver(mobile2);

        // 再次更新天气
        weatherStation.setWeather("多云");
    }
}

输出结果:

天气更新为: 晴天
手机A 收到天气更新: 晴天
手机B 收到天气更新: 晴天
显示屏更新天气: 晴天
天气更新为: 下雨
手机A 收到天气更新: 下雨
手机B 收到天气更新: 下雨
显示屏更新天气: 下雨
天气更新为: 多云
手机A 收到天气更新: 多云
显示屏更新天气: 多云

观察者模式的优点:

  1. 松耦合:主题和观察者之间的耦合性较低,便于扩展和维护。
  2. 动态联动:可以动态地添加或移除观察者,无需修改主题代码。
  3. 灵活性:多个观察者可以独立接收通知,并做出不同的处理。

观察者模式的缺点:

  1. 性能问题:如果观察者过多或通知频繁,可能会影响性能。
  2. 调试困难:通知链较长时,可能难以跟踪状态变化。

观察者模式的适用场景:

  1. 一个对象的改变需要通知其他对象时。
  2. 系统需要动态添加或移除观察者时。
  3. 常见应用场景包括事件监听器、消息队列、发布-订阅系统等。

观察者模式在实际开发中非常常见,比如 GUI 系统中的事件处理(监听器模式)、数据模型与视图的同步(如 MVC 模式)等。

 
posted @ 2025-01-13 16:41  庞某人  阅读(28)  评论(0)    收藏  举报