定义
观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
模式结构
角色职责
1.抽象目标类(Subject):它用一个列表记录当前目标对象有哪些观察者对象,并提供增加、删除观察者对象和通知观察者对象的接口。
2.具体目标类(ConcreteSubject):一个目标对象就是某个具体目标类的对象,一个具体目标类负责定义它自身的事务逻辑,并在状态改变时通知它的所有观察者对象。
3.抽象观察者类(Observer):它为所有的观察者对象都定义了一个名为update的方法(也叫成员函数)。当目标对象的状态改变时,它就是通过调用它的所有观察者对象的update方法来通知它们的。
4.具体观察者类(ConcreteObserver):每个具体观察者类都要重定义Observer类中定义的update方法,在该方法中实现它自己的任务逻辑,当它被通知的时候(目标对象调用它的update方法)就执行自己特有的任务。
代码实现
抽象目标类:
public abstract class Subject {
private LinkedList<MyObserver> observers = new LinkedList<MyObserver>();
public void attachObserver(MyObserver obs) {
observers.add(obs);
}
public void detachObserver(MyObserver obs){
observers.remove(obs);
}
//通知所有的观察者对象
public void notifyObservers() {
for (MyObserver obs : observers) {
obs.update((this));
}
}
}
具体目标类:
public class Weather extends Subject {
private float temp;
public Weather() {
this.temp = -1000;
}
public float getTemperature() {
return this.temp;
}
public void fetchWeatherData() {
float max = 60;
float min = -80;
float newTemp = (float) (Math.random() * (max - min) + min);
if (newTemp != this.temp) {
this.temp = newTemp;
notifyObservers();
}
}
}
抽象观察者:
public interface MyObserver {
public void update(Subject subject);
}
具体观察者:
public class CelsiusView implements MyObserver {
@Override
public void update(Subject subject) {
if (subject instanceof Weather) {
Weather weather = (Weather) subject;
float temperature = weather.getTemperature();
System.out.println("摄氏温度View:" + temperature);
}
}
}
public class WearView implements MyObserver {
@Override
public void update(Subject subject) {
if (subject instanceof Weather) {
Weather weather = (Weather) subject;
float temperature = weather.getTemperature();
if (temperature < 10) {
System.out.println("穿衣服建议View:十分寒冷,请穿羽绒服。");
}else if(temperature < 20){
System.out.println("穿衣服建议View:比较凉爽,多穿点。");
} else if (temperature < 30) {
System.out.println("穿衣服建议View:比较温暖,可以穿薄点。");
} else {
System.out.println("穿衣服建议View:非常炎热,少穿点。");
}
}
}
}
测试结果:
public class App {
public static void main(String[] args) {
Weather weather = new Weather();
//创建两个观察者对象
CelsiusView celsiusView = new CelsiusView();
WearView wearView = new WearView();
weather.attachObserver(celsiusView);
weather.attachObserver(wearView);
weather.fetchWeatherData();
System.out.println("\n");
weather.fetchWeatherData();
}
}
摄氏温度View:14.774444
穿衣服建议View:比较凉爽,多穿点。
摄氏温度View:-64.72526
穿衣服建议View:十分寒冷,请穿羽绒服。
适用场景
1、当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2、当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3、当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。文章来源:https://www.toymoban.com/news/detail-473978.html
优缺点
优点:
1、易于扩展:一个观察目标可以对应多个观察者,而这些观察者之间没有相互联系,所以能够根据需要增加和删除观察者,使得系统更易于扩展,符合开闭原则;
2、松耦合,虽然彼此不清楚对方的细节,但依然可以交互,目标对象只知道一个具体的观察者列表,但并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。
缺点:
1、耗时:如果存在很多个被观察者的话,那么将需要花费一定时间通知所有的观察者。
2、如果观察者与被观察者之间存在循环依赖的话,那么可能导致系统崩溃,并且观察者模式没有相应的机制让观察者知道被观察对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
文章来源地址https://www.toymoban.com/news/detail-473978.html
到了这里,关于java设计模式(二十)观察者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!