观察者模式

观察者模式:

观察者模式使用的场景:

订阅者 + 出版者 = 观察者模式

观察者模式提供了一种对象设计,让观察者和主题之间松耦合。

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖他的对象就会收到通知 ,并自动更新。

有两种对象,双方之间是一对多的关系,一方做出改变时需要通知其他方做改动。使用了观察者模式之后 需要被动做出变化的一方不需要一直查看主题方是否有变化。

使用时的关键之处:

主题提供方有一个专门用来保存观察者列表的list,观察者一方存在一个主题方用来将观察者注册到列表当中。

为了交互对象之间的松耦合设计而努力。

 

实例:

模拟一个气象站的例子   气象站在监测外界的温度  湿度 气压。当这三个要素发生变化时通知其他方发生了变化。

(由主题方维持一个监听方的list  提供注册 删除  通知的接口)

package com.wc.study.observer;

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

具体的通知的方法: 

package com.wc.study.observer;

public interface Observer {
	/**
	 * 更新  温度  湿度  气压
	 * @param temperature
	 * @param humidity
	 * @param pressure
	 */
	void update(float temperature,float humidity, float pressure);
}

监听方用来展示结果的接口方法: 

package com.wc.study.observer;

public interface DisplayElement {
	void display();
}

主题方即本例中的气象站: 

package com.wc.study.observer;

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

public class WeatherData implements Subject{
	private float temperature;
	private float humidity;
	private float pressure;
	private List<Observer> observers = new ArrayList<>();
	
	@Override
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}
	@Override
	public void removeObserver(Observer observer) {
		int index = observers.indexOf(observer);
		if(index >= 0){
			observers.remove(observer);
		}
	}
	@Override
	public void notifyObservers() {
		for(Observer observer : observers){
			observer.update(temperature, humidity, pressure);
		}
	}
	public float getTemperature() {
		return temperature;
	}
	public void setTemperature(float temperature) {
		this.temperature = temperature;
	}
	public float getHumidity() {
		return humidity;
	}
	public void setHumidity(float humidity) {
		this.humidity = humidity;
	}
	public float getPressure() {
		return pressure;
	}
	public void setPressure(float pressure) {
		this.pressure = pressure;
	}
}

监听方具体实现: 

package com.wc.study.observer;

public class ConcreteObserver implements Observer,DisplayElement{
	private float temperature;
	private float humidity;
	private float pressure;
	private Subject subject;
	
	public ConcreteObserver(Subject subject) {
		this.subject = subject;
		subject.registerObserver(this);
	}

	@Override
	public void display() {
		System.out.println( "ConcreteObserver [temperature=" + temperature + ", humidity=" + humidity + ", pressure=" + pressure
				+ "]");
	}

	@Override
	public void update(float temperature, float humidity, float pressure) {
		this.pressure = pressure;
		this.temperature = temperature;
		this.humidity = humidity;
		display();
	}

}
package com.wc.study.observer;

public class DmeoTest {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		weatherData.setHumidity(1.24f);
		weatherData.setPressure(2.32f);
		weatherData.setTemperature(23.4f);
		ConcreteObserver observer1 = new ConcreteObserver(weatherData);
		ConcreteObserver observer2 = new ConcreteObserver(weatherData);
		ConcreteObserver observer3 = new ConcreteObserver(weatherData);
		
		weatherData.notifyObservers();
		
//		ConcreteObserver [temperature=23.4, humidity=1.24, pressure=2.32]
//		ConcreteObserver [temperature=23.4, humidity=1.24, pressure=2.32]
//		ConcreteObserver [temperature=23.4, humidity=1.24, pressure=2.32]
	}
}

观察者模式: 全部都建立接口,主题的一方保留有观察者的列表,用于发生改变时通知。观察者一方留有主题的实现类,用于在创建时注册到列表当中。双方之间通过接口来相互调用,来达到松耦合的目的。

 

JDK实现的观察者模式:

观察者模式如此常用,在jdk中有具体的实现。

java对于观察者模式有自己内置的实现:Observer接口(有观察者一方来实现) Observable(主题的一方来继承)

实例:

package com.wc.study.jdk.observer;

import java.util.Observable;
//主题方
public class WeatherData extends Observable{
	private float temperature;
	private float humidity;
	private float pressure;
	
	public void setWeatherData(float temperature,float humidity,float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		weatherDataChanged();
	}
	
	private void weatherDataChanged() {
		setChanged();
		notifyObservers();
	}

	public float getTemperature() {
		return temperature;
	}
	public float getHumidity() {
		return humidity;
	}
	public float getPressure() {
		return pressure;
	}
	
}
package com.wc.study.jdk.observer;

public interface DisplayElement {
	void display();
}
package com.wc.study.jdk.observer;

import java.util.Observable;
import java.util.Observer;

public class ConcreteObserver implements Observer,DisplayElement{
	private float temperature;
	private float humidity;
	private float pressure;
	private Observable observable;
	
	public ConcreteObserver(Observable observable) {
		this.observable = observable;
		observable.addObserver(this);
	}

	@Override
	public void update(Observable o, Object arg) {
		if(o instanceof WeatherData){
			WeatherData weatherData = (WeatherData)o;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			this.pressure = weatherData.getPressure();
			display();
		}
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("ConcreteObserver [temperature=" + temperature + ", humidity=" + humidity + ", pressure=" + pressure
				+ "]");
	}
}
package com.wc.study.jdk.observer;

public class DemoTest {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		ConcreteObserver concreteObserver1 = new ConcreteObserver(weatherData);
		ConcreteObserver concreteObserver2 = new ConcreteObserver(weatherData);
		ConcreteObserver concreteObserver3 = new ConcreteObserver(weatherData);
		
		weatherData.setWeatherData(1.02f, 2.32f, 23.3f);
		
//		ConcreteObserver [temperature=1.02, humidity=2.32, pressure=23.3]
//		ConcreteObserver [temperature=1.02, humidity=2.32, pressure=23.3]
//		ConcreteObserver [temperature=1.02, humidity=2.32, pressure=23.3]
	}
}

jdk自带的观察者模式存在缺点 : Observable 是一个类没有想用的接口 所以主题的一方需要继承但是java只提供单继承,我们不能提供自己的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值