设计模式——观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。

原理

  • 主题(Subject/发布者): 提供注册和移除观察者的接口,并且在自身状态变化时负责通知所有已注册的观察者。
  • 具体主题(Concrete Subject): 具体实现主题类,通常包含具体的业务逻辑及状态,并持有观察者列表。
  • 观察者(Observer): 定义了一个更新接口,当接收到主题的通知时调用此接口进行相应的操作。
  • 具体观察者(Concrete Observer): 实现观察者接口,其中包含了根据主题状态变化需要做出反应的具体方法。

Java代码示例

java 复制代码
// 观察者接口
import java.util.ArrayList;
import java.util.List;

public interface Observable {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String message);
}

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

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

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

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

    public void setNews(String news) {
        this.news = news;
        // 发布新消息时,通知所有观察者
        notifyObservers(news);
    }
}

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

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

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

    @Override
    public void update(String message) {
        System.out.println(name + " received news: " + message);
        // 在这里执行实际的消息处理逻辑
    }
}

// 客户端使用示例
public class Client {
    public static void main(String[] args) {
        NewsAgency agency = new NewsAgency();
        Observer newspaper1 = new Newspaper("The Daily");
        Observer newspaper2 = new Newspaper("The Times");

        agency.addObserver(newspaper1);
        agency.addObserver(newspaper2);

        agency.setNews("Breaking news!");  // 当发布新消息时,会自动通知所有报纸
    }
}

想象你是一个新闻机构,有很多家报纸订阅你的新闻。每次有新的新闻时,你需要逐一打电话给每一家报纸告诉他们最新消息。在程序世界里,新闻机构就是"主题",而各家报纸是"观察者"。当新闻机构有新消息时,只需调用notifyObservers()方法,就像打一圈电话一样,所有订阅的报纸(观察者)就会自动得到通知并更新自己的内容。

应用

  • 事件驱动编程:如GUI应用中按钮点击事件触发的响应处理。
  • 订阅系统:用户订阅新闻、博客或邮件提醒,当有新内容发布时,系统自动发送通知给所有订阅者。
  • 数据同步:多个模块需要共享同一份数据源,当数据源发生变化时,各模块能够及时得到更新。

适用性

  • 当一个对象的改变需要同时改变其他对象,而且不知道具体有多少对象需要改变时。
  • 当一个对象必须通知其他对象,而并不希望指定这些对象或这些对象只知道有改变发生,而不关心如何得知这一改变时。
相关推荐
2601_967338712 分钟前
尚硅谷2026尚硅谷Java全栈+Python智能体教程
java·人工智能
孙克旭_27 分钟前
单链表进阶实操:5 道常考面试题详细解析【Java 实现】
java·开发语言·数据结构·单链表
2601_9619017033 分钟前
SpringCloud2023集成Nacos2.4.3
java
玄昌盛不会编程34 分钟前
LeetCode——2091. 从数组中移除最大值和最小值
java·算法·leetcode
Rain的Java大神之路37 分钟前
如何保证接口幂等
java·经验分享·后端·面试·架构
吴声子夜歌38 分钟前
Java——数组和集合(一)
java·开发语言
Jesse_EC40 分钟前
一个看不见的字符——CRLF 如何让我的 Docker 初始化脚本"静默失踪"
java·后端
深念Y40 分钟前
Nuxt 项目 Docker 构建:从 pnpm+node 迁移到全 bun
java·前端·docker
学长毕业设计44 分钟前
基于SpringBoot的社区鲜奶订购系统的设计与实现(源码+文档+讲解视频)
java·spring boot·后端
呆呆敲代码的小Y1 小时前
【游戏开发】C# 中的迭代器
java·开发语言·c#·迭代器