设计模式----(二、观察者模式)

二、观察者模式(observer-patterns)

1、引出观察者模式:

Internet 气象站项目,普通OO设计方案,有些问题:

提供温度、气压和湿度的接口,测量数据更新时需要将数据实时通知第三方。需要设计开放API 便于其他第三方公司也能接入气象站获取数据。

2、假设气象站提供了一个WeatherData类获取温度,湿度,气压。

气象站检测到的数据一旦发生改变WeatherData就调用dataChange()方法获取数据。

 3、一个通常的设计方案。

在公告板中有update()和 display();

update() 就是外面有数据的话就给我,然后在display()中显示。

气象站调用dataChange()获取三个参数然后给公告板,公告板获取数据后展示。

代码如下:

package observer.extraction;
/*
 * 获取从气象站提供的天气信息,包含温度、湿度、气压
 */
public class WeatherData {
	private float mTemperatrue;
	private float mPressure;
	private float mHumidity;
	private CurrentConditions CurrentConditions;
	
	public WeatherData(CurrentConditions CurrentConditions) {
		this.CurrentConditions=CurrentConditions;
	}

	public float getmTemperatrue() {
		return mTemperatrue;
	}
	
	public float getmPressure() {
		return mPressure;
	}

	public float getmHumidity() {
		return mHumidity;
	}

	/**
	 * 气象站提供的数据传给公告板
	 */
	public void dataChange() {
		CurrentConditions.update(getmTemperatrue(), getmPressure(), getmHumidity());
	} 
	/**
	 * 假设气象站传数据
	 */
	public void setData(float mTemperatrue,float mPressure,float mHumidity) {
		this.mPressure = mPressure;
		this.mTemperatrue = mTemperatrue;
		this.mHumidity = mHumidity;
		dataChange();
	}
}

package observer.extraction;
/*
 * 公告板
 */
public class CurrentConditions {
	private float mTemperatrue;
	private float mPressure;
	private float mHumidity;
	
	public void update(float mTemperatrue,float mPressure,float mHumidity) {
		this.mPressure = mPressure;
		this.mTemperatrue = mTemperatrue;
		this.mHumidity = mHumidity;
		display();
	}
	
	public void display() {
		System.out.println("****ToDay mTemperatrue"+mTemperatrue);
		System.out.println("****ToDay mPressure"+mPressure);
		System.out.println("****ToDay mHumidity"+mHumidity);
	}
	
	
	
}
package observer.extraction;

public class InternetWeather {
	public static void main(String[] args) {
		CurrentConditions currentConditions = new CurrentConditions();
		WeatherData WeatherData = new WeatherData(currentConditions);
		WeatherData.setData(30,40,500);
	}
}

但是如果说改变需求,如果另外一个公司要新加一个获取一周只能的天气情况的功能。

那么解决方法就是在Weather的 dataChange()方法中添加其他公告板

问题:

1)其他第三方公司接入气象站获取数据的问题。

2)无法在运行时动态的添加第三方。

这就导致了需要很多次编译运行,没有扩展性。

因为公告板有很多种,所以就要将其设计为接口+实现,那么同样的dataChange()由于公告板的变化,它也要设计为接口+实现。

观察者模式原理

1 观察者模式就像定牛奶业务。

 1)奶站,Subject 

2)用户,Observer 

2 、Subject: 登记注册、移除和通知

3、Observer:接收输入

观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject 通过Observer变化

用观察者模式重新设计

 

package observer.produce;

public interface Observer {
	public void update(float mTemperature,float mPressure,float mHumidity);
}

package observer.produce;
/*
 * 公告板
 */
public class ForcastConditions implements Observer {
	private float mTemperatrue;
	private float mPressure;
	private float mHumidity;
	@Override
	public void update(float mTemperatrue,float mPressure,float mHumidity) {
		this.mPressure = mPressure;
		this.mTemperatrue = mTemperatrue;
		this.mHumidity = mHumidity;
		display();
	}
	
	public void display() {
		System.out.println("****ToDay mTemperatrue: "+mTemperatrue);
		System.out.println("****ToDay mPressure: "+mPressure);
		System.out.println("****ToDay mHumidity: "+mHumidity);
	}
	
	
	
}

package observer.produce;
/*
 * 公告板
 */
public class CurrentConditions implements Observer {
	private float mTemperatrue;
	private float mPressure;
	private float mHumidity;
	@Override
	public void update(float mTemperatrue,float mPressure,float mHumidity) {
		this.mPressure = mPressure;
		this.mTemperatrue = mTemperatrue;
		this.mHumidity = mHumidity;
		display();
	}
	
	public void display() {
		System.out.println("****ToDay mTemperatrue: "+mTemperatrue);
		System.out.println("****ToDay mPressure: "+mPressure);
		System.out.println("****ToDay mHumidity: "+mHumidity);
	}
	
	
	
}

package observer.produce;

public interface Subject {
	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObservers();
}

package observer.produce;

import java.util.ArrayList;

/*
 * 获取从气象站提供的天气信息,包含温度、湿度、气压
 */
public class WeatherData implements Subject {
	private float mTemperatrue;
	private float mPressure;
	private float mHumidity;
	private ArrayList<Observer> Observers;
	
	public WeatherData(CurrentConditions CurrentConditions) {
		Observers = new ArrayList<Observer>();
	}

	public float getmTemperatrue() {
		return mTemperatrue;
	}
	
	public float getmPressure() {
		return mPressure;
	}

	public float getmHumidity() {
		return mHumidity;
	}

	/**
	 * 气象站提供的数据传给公告板
	 */
	public void dataChange() {
		notifyObservers();
	} 
	/**
	 * 假设气象站传数据
	 */
	public void setData(float mTemperatrue,float mPressure,float mHumidity) {
		this.mPressure = mPressure;
		this.mTemperatrue = mTemperatrue;
		this.mHumidity = mHumidity;
		dataChange();
	}

	@Override
	public void registerObserver(Observer o) {
		Observers.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		if (Observers.contains(o)) {
			Observers.remove(o);
		}
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		for (Observer observer : Observers) {
			observer.update(getmTemperatrue(), getmPressure(), getmHumidity());
		}
	}
}

package observer.produce;

public class InternetWeather {
	public static void main(String[] args) {
		CurrentConditions currentConditions = new CurrentConditions();
		ForcastConditions forcastConditions = new ForcastConditions();
		WeatherData WeatherData = new WeatherData(currentConditions);
		WeatherData.registerObserver(currentConditions);
		WeatherData.registerObserver(forcastConditions);
		WeatherData.setData(30,40,500);
		System.out.println("-----------------------");
		WeatherData.removeObserver(currentConditions);
		WeatherData.setData(30,40,500);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值