Java23种设计模式之观察者模式(Observer)

观察者模式

(一)概述:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于他的对象都能得到通知并自动刷新
(二)帮助理解:
报社的业务就是出版报纸。
向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户、你就会一直收到新报纸。
当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消订阅报纸。

  • 报社:被观察者
  • 订户:观察者
  • 一个报社对应多个订户

(三)角色

  • Subject:抽象主题(报社这个概念) 其中抽象出来报社所应该有的功能,例如删除和增加.抽象成方法,供以后的实现类进行实现.
  • ConcreteSubject:具体主题(具体到某一个报社),实现抽象主题的抽象方法,当具体主题中的状态发生变化时,给所有的观察者(订户)发送通知.
  • Observer:抽象观察者,()他定义了一个更新接口,用于在主题更改时更新**
  • ConcreteObserver:具体观察者(订户),实现抽象观察者的接口.

代码实现

抽象主题接口

/**
 * * @author 借我丹青妙笔
 * 抽象主题
 */
public interface Subject {
	
	void addObserver(Observer observer);

	void removeObserver(Observer observer);

	void notifyObservers();

}

具体主题类

package com.zking.observer2;

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

/**
 * * @author 借我丹青妙笔
 * 具体实现主题:气象局
 */
public class WeatherData implements Subject {
	double temperature;
	double humidity;
	List<Observer> Observers = new ArrayList<>();

	public WeatherData(double temperature, double humidity) {
		this.temperature = temperature;
		this.humidity = humidity;
	}

	public void update(double temperature, double humidity) {
		this.temperature = temperature;
		this.humidity = humidity;// 气象局数据一改变,马上通知接入的第三方/观察者
		notifyObservers();
	}

	@Override
	public void addObserver(Observer observer) {
		Observers.add(observer);
		observer.update(this.temperature, this.humidity);
	}

	@Override
	public void removeObserver(Observer observer) {
		Observers.remove(observer);
	}

	@Override
	public void notifyObservers() {
		for (Observer observer : Observers) {
			observer.update(this.temperature, this.humidity);
		}
	}
}

抽象观察者接口

package com.zking.observer2;
/**
 * 
 * @author 借我丹青妙笔
 *
 */
public interface Observer {
	void display();

	void update(double temperature, double humidity);
}

具体观察者类

package com.zking.observer2;

/**
 * 
 * @author 借我丹青妙笔
 *
 */
public class Baidu implements Observer {
	double temperature;
	double humidity;

	@Override
	public void display() {
		System.out.println("百度温馨提示:当前温度:" + temperature + ",当前湿度:" + humidity);
	}

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

class Sina implements Observer {
	double temperature;
	double humidity;

	@Override
	public void display() {
		System.out.println("新浪温馨提示:当前温度:" + temperature + ",当前湿度:" + humidity);
	}

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

测试类

package com.zking.observer2;

/**
 * 
 * @author 借我丹青妙笔
 *
 */
public class Client {
	public static void main(String[] args) {
		//实例化气象局(被观察者)
		WeatherData weatherData = new WeatherData(30, 20);
		//实例化观察者
		Baidu baidu = new Baidu();
		Sina sina = new Sina();
		//为观察者提供气象服务
		weatherData.addObserver(baidu);
		weatherData.addObserver(sina);
		System.out.println("----------------------------");
		//更新气象信息
		weatherData.update(10, 10);
		System.out.println("----------------------------");
		//停止为某观察者提供气象服务
		weatherData.removeObserver(baidu);
		//更新气象信息
		weatherData.update(12, 12);
	}
}

打印结果

百度温馨提示:当前温度:30.0,当前湿度:20.0
新浪温馨提示:当前温度:30.0,当前湿度:20.0
----------------------------
百度温馨提示:当前温度:10.0,当前湿度:10.0
新浪温馨提示:当前温度:10.0,当前湿度:10.0
----------------------------
新浪温馨提示:当前温度:12.0,当前湿度:12.0

为什么要使用观察者模式

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

  • 关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。
  • 任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代现有的观察者,主题不会受到任何影响。同样的,也可以在任何时候删除某些观察者。
  • 有新类型的观察者出现时,主题的代码不需要修改。假如我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里匕实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。
  • 我们可以独立地复用主题或观察者。如果我们在其他地方需要使用主题或观察者,可以轻易地复用,因为二者并非紧耦合。
  • 改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。

注意事项

  • Java中已经有了对观察者模式的支持类
  • 避免循环引用
  • 如果顺序执行,某一观察者错误会导致系统卡壳,所以一般采用异步方式.

应用场景

  • JavaBcans
  • RMI
  • JDK源码中Observable类

声明:学习记录,若有错误,欢迎指正。
作者: 借我丹青妙笔

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

借我丹青妙笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值