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.youkuaiyun.com/source/3574114




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值