观察者模式

个人博客地址:https://alexaccele.github.io/

观察者模式

定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

这个模式很好理解,就是多个观察者类观察一个具体的主题,当这个主题改变时,所有的观察者就都知道了这一改变,当某个观察者不再观察这个主题时,则不会注意到这个改变。例如我们生活中的订阅或关注,当你订阅了某个杂志或者关注了某个公众号后,当这个公众号有内容更新,即推送信息时,就会通知你,此时一个公众号就是一个主题,每个用户就是观察者。当你不再关注某个公众号时,则不会再通知你该公众号的相关文章。

案例

这里给出一个案例代码,这是一个对天气实时监控的模拟,当空气中环境变化时,展示板中的内容就会更新,不同的展示板可能可以展示不同的信息,这里只给出一个实例。

主题:在主题中需要有相应的注册观察者,删除观察者,通知观察者的方法

/**
 * 观察者模式中的主题
 *
 */
public interface Subject {
	/**
	 * 用于注册观察者
	 * @param o
	 */
	public void registerObserver(Observer o);
	/**
	 * 用于删除观察者
	 * @param o
	 */
	public void removeObserver(Observer o);
	/**
	 * 用于通知所有的观察者
	 */
	public void notifyObserver();
}

观察者:

/**
 * 观察者
 *
 */
public interface Observer {
	public void update(float temp,float humidity,float pressure);
}

一个展示板的基础接口:

public interface DisplayElement {
	public void display();
}

具体的主题:

/**
 * 一个具体的主题,当发生变化则会通知所有观察者
 *
 */
public class WeatherData implements Subject {
	private ArrayList observers;
	private float temp,humidity,pressure;

	
	public WeatherData() {
		observers = new ArrayList<>();
	}

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

	@Override
	public void removeObserver(Observer o) {
		int i = observers.indexOf(o);
		if(i >= 0)
			observers.remove(i);
	}

	@Override
	public void notifyObserver() {
		for(int i=0;i<observers.size();i++) {
			Observer o = (Observer) observers.get(i);
			o.update(temp, humidity, pressure);
		}
	}
	/**
	 * 当数据更新时调用,用以通知所有的观察者
	 */
	public void measurementsChanged() {
		notifyObserver();
	}

	public void setMeasurements(float temp, float humidity, float pressure) {
		this.temp = temp;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
	//其他方法
}

具体的观察者:

/**
 * 一个具体的观察者
 *
 */
public class CurrentConditionsDisplay implements Observer,DisplayElement{
	private float temp;
	private float humidity;
	private Subject weatherData;
	
	public CurrentConditionsDisplay(Subject weatherData) {
		this.weatherData = weatherData;
		weatherData.registerObserver(this);
	}

	@Override
	public void display() {
		System.out.println("Current conditions: " + temp
				+ "F degrees and " + humidity + "% humidity");
	}

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

}

测试

public class Test {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		CurrentConditionsDisplay display = new CurrentConditionsDisplay(weatherData);
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(83, 75, 29.4f);
		weatherData.setMeasurements(81, 68, 31.4f);
	}
}

结果:

Current conditions: 80.0F degrees and 65.0% humidity
Current conditions: 83.0F degrees and 75.0% humidity
Current conditions: 81.0F degrees and 68.0% humidity

这样就实现了当某个主题发生变化时,观察者就能够知道这一变化,通过注册观察者能够实现添加订阅功能,而删除观察者则可以实现取消关注/订阅等功能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值