尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

0124_观察者模式(Observer)

0124_观察者模式(Observer)
📅 发布时间:2026/6/19 0:30:25

观察者模式(Observer)

意图

定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。

UML 图

Observer

优点

  1. 松耦合:主题和观察者之间抽象耦合,彼此不需要知道具体实现
  2. 支持广播通信:一个主题可以通知多个观察者
  3. 开闭原则:可以轻松添加新的观察者而不修改主题
  4. 状态同步:确保所有观察者及时获得状态变化
  5. 职责分离:将观察者与主题的逻辑分离,提高可维护性

缺点

  1. 通知顺序不可控:观察者收到通知的顺序可能不确定
  2. 性能问题:如果观察者数量很多,通知过程可能耗时
  3. 循环依赖:不正确的实现可能导致循环调用
  4. 内存泄漏:如果观察者没有正确注销,可能导致内存泄漏
  5. 过度更新:细小的状态变化可能触发不必要的更新

代码示例

以机器人和人类为例,机器人做饭后通知人类用餐:

1. 观察者接口 (Observer Interface)

// 观察者接口 - 用餐者
public interface MealObserver {void update(String mealName);String getName();
}

2. 主题接口 (Subject Interface)

// 主题接口 - 厨师
public interface CookSubject {void attach(MealObserver observer);void detach(MealObserver observer);void notifyObservers();
}

3. 具体主题 (Concrete Subject)

// 机器人厨师 - 具体主题
public class RobotCook implements CookSubject {private String currentMeal;private List<MealObserver> observers = new ArrayList<>();@Overridepublic void attach(MealObserver observer) {observers.add(observer);System.out.println(observer.getName() + " 开始等待用餐");}@Overridepublic void detach(MealObserver observer) {observers.remove(observer);System.out.println(observer.getName() + " 取消用餐等待");}@Overridepublic void notifyObservers() {System.out.println("🍳 机器人厨师通知: " + currentMeal + " 已准备好!");for (MealObserver observer : observers) {observer.update(currentMeal);}}// 做饭方法public void cookMeal(String mealName) {System.out.println("🤖 机器人开始烹饪: " + mealName);this.currentMeal = mealName;// 模拟烹饪过程try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}mealReady();}private void mealReady() {System.out.println("✅ " + currentMeal + " 烹饪完成!");notifyObservers();}public String getCurrentMeal() {return currentMeal;}
}

4. 具体观察者 (Concrete Observers)

// 人类 - 具体观察者
public class Human implements MealObserver {private String name;public Human(String name) {this.name = name;}@Overridepublic void update(String mealName) {System.out.println("📢 " + name + " 收到通知: " + mealName + " 已准备好!");eat(mealName);}public void eat(String mealName) {System.out.println("🍽️ " + name + " 正在享用: " + mealName);}@Overridepublic String getName() {return name;}
}// 其他类型观察者 - 比如另一个机器人也可以观察
public class OtherRobot implements MealObserver {private String name;public OtherRobot(String name) {this.name = name;}@Overridepublic void update(String mealName) {System.out.println("🔋 " + name + " 收到通知: 开始充电模式");// 机器人可能不需要吃饭,但可以执行其他操作}@Overridepublic String getName() {return name;}
}

5. 客户端代码 (Client Code)

public class ObserverPatternDemo {public static void main(String[] args) {// 创建机器人厨师RobotCook robotCook = new RobotCook();// 创建人类观察者Human john = new Human("John");Human alice = new Human("Alice");Human bob = new Human("Bob");// 创建其他类型观察者OtherRobot helperBot = new OtherRobot("HelperBot");// 注册观察者robotCook.attach(john);robotCook.attach(alice);robotCook.attach(helperBot);System.out.println("\n=== 第一次烹饪 ===");// 机器人开始做饭robotCook.cookMeal("红烧牛肉面");System.out.println("\n=== 调整观察者 ===");// Bob加入等待,Alice取消等待robotCook.attach(bob);robotCook.detach(alice);System.out.println("\n=== 第二次烹饪 ===");// 机器人做另一顿饭robotCook.cookMeal("蔬菜沙拉");}
}

在Java标准库中的应用

观察者模式在Java标准库中有广泛应用:

  1. JavaBeans属性变更监听
// 属性变更支持
public class BeanWithProperty {private String value;private PropertyChangeSupport support = new PropertyChangeSupport(this);public void setValue(String newValue) {String oldValue = this.value;this.value = newValue;support.firePropertyChange("value", oldValue, newValue);}public void addPropertyChangeListener(PropertyChangeListener listener) {support.addPropertyChangeListener(listener);}
}
  1. Swing事件监听
JButton button = new JButton("Click me");
// 添加观察者(事件监听器)
button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}
});
  1. JavaFX属性绑定
SimpleStringProperty name = new SimpleStringProperty("John");
// 观察属性变化
name.addListener((observable, oldValue, newValue) -> {System.out.println("Name changed from " + oldValue + " to " + newValue);
});
  1. Servlet上下文监听
@WebListener
public class AppContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {// 应用启动时通知}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 应用关闭时通知}
}

总结

观察者模式通过定义一对多的依赖关系,实现了对象间的松耦合通信。在机器人做饭通知人类的例子中,机器人作为主题负责状态改变和通知,人类作为观察者接收通知并作出响应。这种模式特别适合需要实现事件通知、状态同步和动态响应的场景,如GUI事件处理、消息推送系统、实时数据更新等。Java标准库中的事件监听机制和属性变更通知都是观察者模式的典型应用。

相关新闻

  • 洛谷P5854 【模板】笛卡尔树 题解 笛卡尔树模板题
  • 都江堰操作系统
  • [OLAP/Doris] Doris 之表设计

最新新闻

  • AI大模型benchmark解密:MMLU、GPQA、BBH等五大评测原理与实战解读
  • 深耕洪城防水领域 匠心守护安居|微顺虹防水:初心筑品质,服务护万家 - 徽顺虹
  • 跌倒亦是成长的勋章
  • C# .NET 构建高性能WebSocket服务端:从Fleck入门到实战优化
  • FanControl V270深度解析:Windows风扇控制的5个专业技巧与完整架构指南
  • 如何用ExplorerPatcher重塑Windows 11操作习惯:新手也能掌握的完整改造指南

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号