JDK的观察者模式

1. JDK中实现观察者模式通过Observale类(顾名思义可以被观察)与Observer接口(观察者),被观察者继承Observale类,观察者实现Observer接口,类图如下:
[img]http://dl.iteye.com/upload/attachment/482004/836e3b6d-4c1d-3a72-8157-ca735bf7fee7.png[/img]
2.Observale类是线程安全的,通过Vector存储所有的观察者。同步方法实现观察者的添加、删除、被观察者的状态改变。
如:
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) { //调用Vector 的contains方法判断是否包含某个Observer对象,当且仅当 equals 方法为两个观察者返回 true 时
obs.addElement(o);
}
}
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg); //通知多个观察者,执行观察方法。
}

3.代码示例,假设论坛在发表帖子后,需要给订阅帖子用户发送链接。
提交帖子:
package design;
import java.util.Observable;
public class Topic extends Observable {
public String submitTopic(String topic){
this.setChanged();//开启观察
this.notifyObservers(topic);//通知观察者
System.out.println("提交帖子:"+topic);
return topic == null ? "null":topic;
}
}
观察者发送邮件:
package design;
import java.util.Observable;
import java.util.Observer;
public class TopicObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
submitTopicLog(arg.toString());
}
public void submitTopicLog(String str){
System.out.println("发送邮件:"+str);
}
}
调用:
package design;
public class forkObserver {
public static void main(String[] args) {
Topic t = new Topic();
TopicObserver to = new TopicObserver();
t.addObserver(to); //注册观察者
System.out.println(t.countObservers());
t.submitTopic("hello, every one!!!");
}
}
4.系统中可能需要在方法执行前、执行后进行跟踪反馈,
<think>好的,用户现在想了解JDK中对观察者模式的支持,特别是使用java.util.Observer和java.util.Observable的例子。我之前已经回答过关于用Python实现观察者模式的问题,现在用户需要转到Java,并且引用了相关的资料。 首先,我需要确认用户的需求。他们希望看到JDK自带的观察者模式实现,也就是如何使用Observable类和Observer接口。用户提供的引用内容中有几个示例代码,比如TestObservable类和Student、Teacher的例子,还有ConcreteObserver的实现。我需要参考这些例子,并生成一个清晰的Java示例。 接下来,我需要回忆JDK中这两个类的用法。Observable是一个类,被观察者需要继承它,而Observer是一个接口,观察者需要实现它。在Java中,由于单继承的限制,被观察者必须继承Observable,这可能是一个缺点,但用户已经提到这一点,所以需要指出。 然后,考虑如何构建示例。可能需要一个主题类,比如学生信息变化,被观察者继承Observable,当属性变化时调用setChanged()和notifyObservers()。观察者比如老师,实现update方法,接收通知。 用户提供的引用中有Student和Teacher的例子,但代码可能有错误,比如s1.addObserver(teacher)被调用了两次,这可能重复注册。需要注意正确的使用方法,并解释每个步骤。 另外,需要提到JDK 9之后这两个类被弃用,推荐使用PropertyChangeListener或其他实现方式。但用户可能还在使用旧版本,所以需要说明。 步骤应该是:定义被观察者继承Observable,设置变化后通知;观察者实现Observer接口,注册到被观察者。在示例中,当学生的姓名改变时,触发通知,观察者打印信息。 还需要指出代码中的关键点,比如setChanged()的必要性,以及如何传递参数。可能还需要对比之前Python的实现,说明Java的不同之处。 最后,确保代码示例正确,没有语法错误,并且注释清晰,用户能理解每个部分的作用。同时,回答用户的问题后,生成相关问题,比如弃用后的替代方案,或者处理多个被观察者的情况。</think>### JDK观察者模式实现详解 #### 1. 核心类说明 JDK通过`java.util.Observable`类和`java.util.Observer`接口提供观察者模式支持: - **Observable**:被观察者基类,内置观察者注册/通知机制 - **Observer**:观察者接口,需实现`update()`方法 > 注意:这两个类在JDK 9后被标记为`@Deprecated`,但仍是理解观察者模式的标准实现[^1] #### 2. 典型场景实现 实现学生信息变更通知系统: ```java import java.util.Observable; import java.util.Observer; // 被观察者(继承Observable) class Student extends Observable { private String name; private int score; public void updateInfo(String newName, int newScore) { if (!name.equals(newName) || score != newScore) { this.name = newName; this.score = newScore; setChanged(); // 标记状态变化 notifyObservers(this); // 推送当前对象 } } // Getter方法省略... } // 观察者(实现Observer接口) class Teacher implements Observer { @Override public void update(Observable o, Object arg) { if (o instanceof Student) { Student s = (Student) o; System.out.printf("[教师端] 学生信息更新:%s 成绩=%d%n", s.getName(), s.getScore()); } } } // 观察者(实现Observer接口) class Parent implements Observer { @Override public void update(Observable o, Object arg) { if (o instanceof Student) { System.out.println("[家长端] 收到学生信息变动通知"); } } } ``` #### 3. 系统运行示例 ```java public class Main { public static void main(String[] args) { Student student = new Student(); Teacher teacher = new Teacher(); Parent parent = new Parent(); // 注册观察者 student.addObserver(teacher); student.addObserver(parent); // 触发更新 student.updateInfo("张三", 85); // 所有观察者都会收到通知 student.updateInfo("张三", 90); // 仅成绩变化触发通知 } } ``` #### 4. 关键方法解析 - `setChanged()`:标记状态变化(必须调用才会触发通知) - `notifyObservers(arg)`:参数会传递给观察者的`update`方法 - `hasChanged()`:检查是否处于变化状态 #### 5. 执行结果示例 ``` [家长端] 收到学生信息变动通知 [教师端] 学生信息更新:张三 成绩=85 [家长端] 收到学生信息变动通知 [教师端] 学生信息更新:张三 成绩=90 ``` ### 设计注意事项 1. **单继承限制**:被观察者必须继承`Observable`,可能影响类层次结构 2. **推送策略**:默认采用`push`模式(主动发送数据),也可实现`pull`模式(观察者主动拉取) 3. **线程安全**:`Observable`的方法未同步,多线程环境需自行处理 ### 替代方案(JDK 9+) 推荐使用`java.beans.PropertyChangeSupport`实现观察者模式: ```java // 更灵活的事件驱动模型 PropertyChangeSupport support = new PropertyChangeSupport(this); support.addPropertyChangeListener(evt -> { System.out.println("属性变更:" + evt.getPropertyName()); }); ``` ### 相关问题 1. 为什么JDK要弃用Observable/Observer? 2. 如何实现观察者模式的线程安全版本? 3. 观察者模式Java事件监听机制有何异同?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值