是什么?java
怎么用?设计模式
什么状况下用?ide
实例!函数
观察者模式:this
一个目标对象管理全部依赖于它的观察者对象,而且当它自己的状态改变时主动发出通知。spa
这时候就有问题了,目标怎么知道谁是观察者?谁不是观察者?并且目标要怎么通知观察者?设计
(我的感受两个类通讯就能用到这东西)code
使用场景:server
今日头条文章发布后须要一系列的后续处理流程,好比更新这个做者建立的文章总数、将这篇文章推荐到对应的频道、划分文章的栏目、上报到推荐系统等等。那要其余的这些要怎么知道文章是否发布呢?这时候就能够用到观察者模式了(事件机制)!对象
原理:
目标类须要:
一、注册观察者(观察者通知目标:我要当你的观察者)
二、移除观察者(观察者通知目标:我要溜了)
三、调用观察者的提供的方法通知观察者
观察者须要:
一、提供目标通知观察者时用到的方法
二、在构造函数中调用目标的注册方法将本身注册成目标的观察者
例子:
气象检测例子:
如图,气象站是获取实际气象数据的物理设备,WeatherData对象是用来追踪气象站的数据,并更新布告板。
扩充WeatherData对象,使得布告板可以及时更新,并利于之后的扩展。
Subject 是抽象目标,全部的目标都继承这个抽象类,这个抽象类提供了三个最基本的注册、移除、通知观察者的方法!
WeatherData 是具体目标,继承自抽象目标Subject,这个类的notifyObserver经过调用观察者的udpate方法通知观察者状态变化!
Observer 是抽象观察者,全部的观察者都继承这个抽象类,这个抽象类提供了udpate方法,以便目标调用。
CurrentConditionDisplay、StatisticsDisplay 是具体观察者,在这两个类的构造方法中实现了「注册为目标的观察者」!
<Head First 设计模式> code:
package Observer; public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObserver(); }
package Observer; import java.util.ArrayList; public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList(); } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } public void notifyObserver() { for (int i =0; i< observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
package Observer; public interface Observer { public void update(float temp, float humidity, float pressure); }
package Observer; public class CurrentConditionsDisplay implements Observer { private float temperature; private float humidity; private float pressure; private Subject weatherDay; public CurrentConditionsDisplay(Subject subject) { this.weatherDay = subject; weatherDay.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; display(); } public void display() { System.out.println("temp = " + temperature + " humi = " + humidity + " press = " + pressure); } }
package com.company; import Observer.CurrentConditionsDisplay; import Observer.WeatherData; public class Main { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(1, 3, 4); } }
结果:
temp = 1.0 humi = 3.0 press = 4.0