Observer学习笔记
首先还是先来observer模式的uml图
Suject实际是被订阅的消息主题,比如报社,中国移动的天气预报套餐,。。。在Suject中保存了所有订阅者的引用,以便在通知订阅者时使用
Observer就是订阅者了,相当于就是订阅报纸的人了
在JDK中java.util.Observerable实现了Suject的功能,内部是通过线程安全的Vector保存所有订阅者的引用,在发送订阅消息是需通过setChanged();修改其状态值才能对订阅者发送消息,发送消息的顺序是先订阅后发送的顺序,这点需要注意。
java.util.Observer是一个接口,其中定义了update(Observerable o,Object arg)方法,第一个参数是被订阅者,可以让观察者知道是哪一个主题发送的消息,第二个参数是具体订阅的消息
在java awt的事件监听就是使用的观察者模式,需要对一个组件进行监听使用setXXlistenner进行监听
下面介绍一个简单的例子
房屋中介提供房屋出售的信息和房屋出租的信息,那么就可以让房屋中介继承Observerable
有的买房者对房屋中介的房屋出售价格感兴趣,有的对所有信息感兴趣,他可以对自己感兴趣的信息进行订阅,买房者实现Observer接口
一个房屋中介的简单代码
package com.akwolf.observer; import java.util.Observable; /** * 房屋中介提供房屋价格变化的信息,也包括房屋出租等信息 在Observer中保存了Observer的应用使用vector实现 * * @author zhanghua * */ public class HouseAgency extends Observable { /** 房屋中介所能提供的信息 */ private HouseAgencyInfo agencyInfo; public HouseAgency() { agencyInfo = new HouseAgencyInfo(); } public void notifyAllObservers(HouseAgencyInfo oldInfo, HouseAgencyInfo newInfo) { //System.out.println(oldInfo+"-----"+newInfo); // 这里可以控制房屋中介不用太敏感,当房屋出售价格的变动大于100时通知观察者 if (Math.abs(newInfo.getHousePrice() - oldInfo.getHousePrice()) > 100) { // 设置为通知状态,不设置的话观察者无法获取信息 setChanged(); notifyObservers(newInfo); } } public HouseAgencyInfo getAgencyInfo() { return agencyInfo; } public void setAgencyInfo(HouseAgencyInfo agencyInfo) { // 保存价格变动前的信息 HouseAgencyInfo oldInfo = this.agencyInfo; this.agencyInfo = agencyInfo; notifyAllObservers(oldInfo, agencyInfo); } }几个订阅者的代码,只列出一个观察者的代码 package com.akwolf.observer; import java.util.Observable; import java.util.Observer; public class Jack implements Observer { @Override public void update(Observable o, Object arg) { if (o instanceof HouseAgency) { // Jack只对房屋出售价格感兴趣,所以他可以使用“拉”的方式从房屋中介获得信息 HouseAgency agency = (HouseAgency) o; System.out.println("Jack收到的消息--"+agency.getAgencyInfo().getHousePrice()); } } }
写一个测试类对房屋信息和观察者进行测试
package com.akwolf.observer; public class MainTest { public static void main(String[] args) { //创建被观察者实例 HouseAgency houseAgency = new HouseAgency() ; //创建观察者实例 Jack jack = new Jack() ; Tom tom = new Tom() ; Jim jim = new Jim() ; //观察者订阅主题关注自己所关注的信息 houseAgency.addObserver(jack) ; houseAgency.addObserver(tom) ; houseAgency.addObserver(jim) ; //ok,现在房屋的价格发生变化了 HouseAgencyInfo agencyInfo = new HouseAgencyInfo(6000,800) ; houseAgency.setAgencyInfo(agencyInfo) ; System.out.println("-------1-------"); //房屋的变化信息小于100,所有订阅者不会收到消息 agencyInfo = new HouseAgencyInfo(6010,800) ; houseAgency.setAgencyInfo(agencyInfo) ; System.out.println("-------2-------"); //房屋的信息大于100 agencyInfo = new HouseAgencyInfo(7000,850) ; houseAgency.setAgencyInfo(agencyInfo) ; System.out.println("----3-----"); //Tom已经买房子了,所以不再对房屋中介的信息感兴趣,他退订了信息 houseAgency.deleteObserver(tom) ; //房屋价格再次变化 agencyInfo = new HouseAgencyInfo(8000,100) ; houseAgency.setAgencyInfo(agencyInfo) ; } }测试结果
ok到这里观察者模式的小例子介绍完毕,有不明白的童鞋和认为我讲的不对的童鞋欢迎拍砖,一起讨论进步!!
附上源码下载地址:http://download.****.net/source/3574114