当前位置: 首页 > news >正文

0124_观察者模式(Observer)

观察者模式(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标准库中的事件监听机制和属性变更通知都是观察者模式的典型应用。

http://www.sczhlp.com/news/86261/

相关文章:

  • 网站首页布局的设计网站开发语言数据库有几种
  • 外贸网站推广 上海文化墙创意设计图片
  • 建筑型专业网站有哪些建设好网站的在线沟通功能
  • 大连市营商环境建设局门户网站音乐网站的音乐怎么做音乐试听
  • 网站建设和网页设计pdf网页图片素材
  • 菏泽 做网站 多少钱seo内部优化具体做什么
  • 做网站哪家公司个人网站有备案吗
  • 公司网站域名主机北湖建设局网站
  • 免费网站模板下载网站利用jquery做音乐网站
  • 网站开发 案例如何自建一个网站
  • 亳州电子商务网站建设公司母婴网站模板
  • 读人形机器人07零售行业
  • 徐州网站排名wordpress 默认模板
  • 线上做图的网站东莞网站设计如何
  • 一站式快速网站排名多少钱网页设计师培训班合肥
  • 重庆靓号网站建设执法网站建设方案
  • 医疗设计网站wordpress支付宝付费
  • 烟台网站排名系统建筑公司简介模板范文
  • 做seo要明白网站内容济南网站建设(选 聚搜网络)
  • 廊坊高端模板建站wordpress oa系统
  • 四川成都网站网页设计婴幼儿网站模板
  • 建立一个自己的网站需要多少钱个人如何接网站建设订单
  • 西安做网站培训博客网站开发利用数据库
  • 奇网企业网站管理系统专业设计自学网站
  • 万网免费建企业网站网站空间的分类
  • 做百度网站一般多少钱做网站预付款 怎么做账
  • 销售管理软件系统石家庄全网seo
  • 广州一起做网店网站哪个地方网站建设的公司多
  • 商业网站建设案例课程百度云WordPress 网站小图标
  • 响应式网站建设推荐乐云seo网站网页设计屏幕尺寸