2023年10月21日 2 分钟阅读

观察者模式(Observer Pattern)

tinyash 0 条评论
blog16

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。观察者模式也被称为发布-订阅模式。

结构

  • 主题(Subject): 维护一组观察者对象,提供注册和删除观察者的接口,以及通知观察者的方法。
public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
  • 具体主题(Concrete Subject): 实现主题接口,维护观察者列表,并在状态变化时通知观察者。
public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

    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(state);
        }
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }
}
  • 观察者(Observer): 定义了一个更新方法,用于接收主题的通知。
public interface Observer {
    void update(int state);
}
  • 具体观察者(Concrete Observer): 实现观察者接口,用于处理主题的通知。
public class ConcreteObserver implements Observer {
    private int observerState;

    public void update(int state) {
        observerState = state;
        System.out.println("Observer updated with state: " + observerState);
    }
}

优点和缺点

优点:

  1. 松耦合: 观察者模式实现了主题和观察者之间的松耦合关系,主题不需要知道观察者的具体细节。
  2. 可扩展性: 可以很容易地增加或删除观察者,而不会影响主题的代码。
  3. 通知机制: 主题状态的变化会自动通知所有的观察者,确保观察者与主题状态保持同步。

缺点:

  1. 可能导致性能问题: 如果观察者很多,同时主题频繁变化,可能会导致性能问题。
  2. 可能引入循环依赖: 如果不小心设计,可能会出现观察者之间的循环依赖。

示例

以下是一个观察者模式的示例,模拟了一个气象站,主题对象为气象数据,观察者对象为显示器和日志记录器。

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

// 具体主题 - 气象数据
public class WeatherData implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature;

    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(temperature);
        }
    }

    public void setTemperature(float temperature) {
        this.temperature = temperature;
        notifyObservers();
    }
}

// 观察者接口
public interface Observer {
    void update(float temperature);
}

// 具体观察者 - 显示器
public class Display implements Observer {
    public void update(float temperature) {
        System.out.println("Display: Temperature is " + temperature);
    }
}

// 具体观察者 - 日志记录器
public class Logger implements Observer {
    public void update(float temperature) {
        System.out.println("Logger: Logging temperature data: " + temperature);
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        Observer display = new Display();
        Observer logger = new Logger();

        weatherData.registerObserver(display);
        weatherData.registerObserver(logger);

        weatherData.setTemperature(25.5f); // 触发观察者更新
    }
}

在这个示例中,WeatherData 是具体主题,维护观察者列表,当温度数据发生变化时,会通知所有观察者。Display 和 Logger 分别是具体观察者,它们实现了 Observer 接口,当收到通知时,会更新显示温度或记录温度日志。客户端代码创建了主题和观察者对象,并将观察者注册到主题上,当温度发生变化时,观察者会被自动通知。

精选推荐 RECOMMEND
阿里云
前往领券

☁️ 阿里云新客专享

🎁 新用户 8 折优惠,云服务器、建站套餐都能省一笔

新用户专享,个人建站从这里开始

腾讯云
点击查看

🚀 腾讯云活动专区

💻 4核4G服务器新客 38元/年起,香港地域低至 6.5 折/月

活动价格以官网为准

🙋 蹲队友拼智谱 Coding Plan!

🧩 国内顶流编程大模型,20+ 主流工具全适配,性价比拉满

每日 10 点抢购

阿里云
领养龙虾

🦞 OpenClaw

⚡ 分钟级部署 OpenClaw,低至 68 元 1 年,专属你的 AI 管家

自动帮你干活,适合个人和团队

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。

工具站推荐 TINYASH TOOL HUB

效率工具,一站直达

常用工具都在这里,打开即用 www.tinyash.com/tool

Markdown 图片处理 开发调试 效率工具