java设计模式之观察者模式

一,背景

观察者模式在我们的工作中很多地方都有用到,如果学会了会为我们代码的健壮性增色不少.首先所谓观察者模式,是一对多的,本例中以气象站为例,一个气象站就相当于一个主题,也就是消息的提供者,而多个天气显示器就是相当于我们的观察者,也就是消息的接收者.当气象站的天气发生变化时,多个显示器显示的信息也会发生变化.

二,设计思路

首先我们应该在气象站中留有注册显示器的方法,移除显示器的方法,以及通知天气变化的方法

其次我们写一个显示器接口,其中我们应该有一个更新天气变化的方法

在气象站与显示器交互的过程中我们只知道他们的接口方法.而并不知道具体是怎么实现的.

三,类图

四,代码

1,主题(被观察者)

package com.yxf.designpattern.observer.gama;
/**
 * 主题接口
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:17:12
 */
public interface Subject {
	void registerObserver(Observer observer);
	void removeObserver(Observer observer);
	void notifyObserver();
	void setChange();
	void clearChange();
	boolean hasChange();
}

 

package com.yxf.designpattern.observer.gama;

import java.util.ArrayList;
import java.util.List;

/**
 * 主题实现类
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:26:31
 */
public class WeatherData implements Subject {

	private List<Observer> observerList;
	
	private  boolean change;
	
	private Weather weather;
	
	public WeatherData(){
		if(null == observerList){
			observerList = new ArrayList<Observer>();
		}
	}
	
	@Override
	public void registerObserver(Observer observer) {
		observerList.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		if(observerList.indexOf(observer) == -1){
			return;
		}
		observerList.remove(observer);
	}

	@Override
	public void notifyObserver() {
		if(!change){
			return;
		}
		for (int i = 0; i < observerList.size(); i++) {
			observerList.get(i).update(weather);
		}
		clearChange();
	}
	
	public void changeMethod(Weather weather){
		setWeather(weather);
		notifyObserver();
	}

	@Override
	public void setChange() {
		change = true;
	}

	@Override
	public void clearChange() {
		change = false;
	}

	@Override
	public boolean hasChange() {
		return change;
	}
	
	public void setWeather(Weather weather){
		this.weather = weather;
	}

}

2,观察者 

package com.yxf.designpattern.observer.gama;
/**
 * 观察者
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:17:05
 */
public interface Observer {
	/**
	 * 更新天气
	 * @description
	 * @param
	 * @return
	 */
	void update(Weather weather);

}

 

package com.yxf.designpattern.observer.gama;
/**
 * 显示接口
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:37:27
 */
public interface DisplayElement {
	void display();
}
package com.yxf.designpattern.observer.gama;

/**
 * 温度显示器
 * @Description
 * @author yxf
 * @time 2018-8-21上午11:45:17
 */
public class TempDisplay implements Observer,DisplayElement{

	
	private Weather weather;
	
	@Override
	public void display() {
		System.out.println("温度显示器显示的当前温度为:"+weather.getTemp());
	}

	@Override
	public void update(Weather weather) {
		this.weather  = weather;
		display();
	}


}
package com.yxf.designpattern.observer.gama;
/**
 * 湿热显示器
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:53:07
 */
public class MuggyDisplay implements Observer,DisplayElement{

	private Weather weather;
	
	@Override
	public void display() {
		System.out.println("湿热显示器显示的湿热比为:"+weather.getHumidity()/weather.getTemp());
	}

	@Override
	public void update(Weather weather) {
		this.weather = weather;
		display();
	}

}
package com.yxf.designpattern.observer.gama;

/**
 * 压力显示器
 * @Description
 * @author yxf
 * @time 2018-8-21上午11:12:20
 */
public class PressureDisplay implements Observer,DisplayElement{

	public Weather weather;
	
	@Override
	public void display() {
		System.out.println("压力显示器显示的压力为:"+weather.getPressure());
	}

	@Override
	public void update(Weather weather) {
		this.weather = weather;
		display();
	}

}
package com.yxf.designpattern.observer.gama;
/**
 * 天气对象
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:21:51
 */
public class Weather {
	/**
	 * 温度
	 */
	public double temp;
	/**
	 * 湿度
	 */
	public double humidity;
	/**
	 * 压力
	 */
	public double pressure;
	
	public Weather() {
	}
	
	public Weather(double temp, double humidity, double pressure) {
		this.temp = temp;
		this.humidity = humidity;
		this.pressure = pressure;
	}
	
	public double getTemp() {
		return temp;
	}
	public void setTemp(double temp) {
		this.temp = temp;
	}
	public double getHumidity() {
		return humidity;
	}
	public void setHumidity(double humidity) {
		this.humidity = humidity;
	}
	public double getPressure() {
		return pressure;
	}
	public void setPressure(double pressure) {
		this.pressure = pressure;
	}
	
	
}

3,测试入口

package com.yxf.designpattern.observer.gama;
/**
 * 测试main
 * @Description
 * @author yxf
 * @time 2018-8-21上午10:55:38
 */
public class MainTest {
	public static void main(String[] args) {
		//主题对象
		WeatherData weatherData = new WeatherData();
		//初始化温度\湿热\压力显示器
		Observer tempDisplay = new TempDisplay();
		Observer muggyDisplay = new MuggyDisplay();
		Observer pressureDisplay = new PressureDisplay();
		//注册观察者
		weatherData.registerObserver(tempDisplay);
		weatherData.registerObserver(muggyDisplay);
		//设置推送状态
		weatherData.setChange();//可用来控制什么时候才向观察者推送 --例如温度上升5度时才推送,位置可调整
		System.out.println("====================第一次天气变化=================");
		//天气变化
		weatherData.changeMethod(new Weather(30, 15, 45));
		
		System.out.println("====================第二次天气变化=================");
		//移除天气显示器
		weatherData.removeObserver(tempDisplay);
		//注册压力显示器
		weatherData.registerObserver(pressureDisplay);
		//设置推送状态
		weatherData.setChange();
		//天气变化
		weatherData.changeMethod(new Weather(24, 19.7, 52));
		
		
	}
}

五,总结

在jdk中就自带的Observable类,但是由于它不是一个接口,可扩展性低.所以可以自己来写观察者模式,面向接口编程能够提高代码的可扩展性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值