设计模式之观察者模式


1 观察者模式概述

观察者模式定义了数据对象之间一对多的依赖关系,当中心对象发生变化时,所有依赖该中心对象的数据对象会收到通知并自动更新。为了更加形象的描述本模式,可以用报纸订阅服务来比拟。

报纸服务是这样的:

1 报社出版报纸

2 用户向报社订阅报纸,只要报社有新报纸就通知用户收取新报纸

3 用户向报社取消订阅,那么报社就不在通知用户收取报纸

4 只要报社没有倒闭,就一直会有人订阅报纸

在这里,报社称为“主题”(subject),订阅报纸的用户称为“观察者”(observer)。报社+订阅者=观察者模式。下图可以形象的描述观察者模式的流程:


2 观察者模式角色组成

观察者模式一般拥有四种角色:抽象主题,具体主题,抽象观察者和具体观察者。

     抽象主题是一个接口,把所有观察者对象的引用保存在一个聚集里。

    具体主题,实现抽象主题中接口

    抽象观察者:所有观察者必须实现观察者接口,这个接口只有一个update()方法,当主题状态变化时被调用。

   具体观察者:实现抽象观察者接口。

观察者模式类图:


3 代码实现:

下面结合实例,实现观察者模式代码。

事例描述:气象站追踪气象数据(温度,湿度,气压),更新发布版中气象数据。

类图:

根据类图编写代码,首先实现抽象主题代码:

public interface Subject {
	public void registerObserver(Observer o);//注册观察者
	public void removeObserver(Observer o);//删除观察者
	public void notifyObserver();//当主题对象数据发生变化时,被调用
}
抽象观察者:

public interface Observer {
	public void update(float temperature,float humidity,float pressure);
}
public interface DisplayElement {
	public void display();
}
主题对象WeatherData:

WeatherData对象实现了Subject接口。使用ArrayList来存储Observer对象,当注册观察者时,只要把它加到ArrayList后面即可。notifyObserver方法为把现在的状态通知到每一个观察者,因为每一个观察者都实现了update方法。

package observer.weather;

import java.util.ArrayList;

public class WeatherData implements Subject{
	private ArrayList observer;
	private float temperature;
	private float humidity;
	private float pressure;
	

	public WeatherData(){
		observer = new ArrayList();
	}
	
	@Override
	public void registerObserver(Observer o) {
		// TODO Auto-generated method stub
		observer.add(o);
		
	}

	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		int i = observer.indexOf(o);
		if(i>=0){
			observer.remove(i);
		}
		
	}

	@Override
	public void notifyObserver() {
		// TODO Auto-generated method stub
		for(int i=0;i<observer.size();i++){
			Observer ob = (Observer) observer.get(i);
			ob.update(temperature, humidity, pressure);
		}
	}
	
	public void measurementsChanged(){
		notifyObserver();
	}
	
	public void setMeasurements(float temperature,float humidity,float pressure){
		this.temperature=temperature;
		this.humidity=humidity;
		this.pressure=pressure;
		measurementsChanged();
	}

}
观察者对象:

package observer.weather;

public class CurrentConditionDisplay implements Observer,DisplayElement{

	private float tempetature;
	private float humidity;
	private float pressure;
	private Subject weatherData;
	//注册观察者
	public CurrentConditionDisplay(Subject weatherData){
		this.weatherData =  weatherData;
		weatherData.registerObserver(this);
	}
	
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("tempetature="+tempetature+" humidity="+humidity+" perssure="+pressure);
		
	}

	@Override
	public void update(float temperature, float humidity, float pressure) {
		// TODO Auto-generated method stub
		this.tempetature=temperature;
		this.humidity=humidity;
		this.pressure=pressure;
		display();<pre name="code" class="java"><span style="font-family: Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; widows: auto;">	}</span>
}

 最后建立一个测试程序: 

package observer.weather;

public class WeatherStation {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		WeatherData weatherData = new WeatherData();
		CurrentConditionDisplay currentConditionDisplay = 
				new CurrentConditionDisplay(weatherData);
		weatherData.setMeasurements(12, 0, 1);
		weatherData.setMeasurements(1, 10, 11);
		weatherData.setMeasurements(19, 13, 31);
	}

}

运行结果:





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值