报纸和杂志的订阅是怎么一回事?
1.报社的业务就是出版报纸
2.向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来,只要你是他们的订户,你就会一直收到新报纸
3.当你不想在看报纸的时候,取消订阅,他们就不会再送新报纸来
4.只要报社还在运营,就会一直有人向他们订阅报纸或取消报纸
观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
观察者模式是松耦合的,改变主题或者观察者其中一方都不会影响另一方
设计原则:为了交互对象之间的松耦合设计而努力
观察者模式类图:
需求:
有一个气象站,可以获得三个测量数据,分别是温度,湿度和气压
当气象站获得最新的测量数据时,就需要通知布告版
布告板目前有三种,分别是目前状况,气象统计,和天气预报
扩展要求,布告板可以随心所欲的添加或者删除
代码来实现一下这个类图
package com.alvin.observer.self;
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
void setMeasurementChanged(float temperature, float humidity, float pressure);
}
package com.alvin.observer.self;
public interface Observer {
void update(float temperature,float humidity,float pressure);
}
package com.alvin.observer.self;
public interface DisplayElement {
void display();
}
package com.alvin.observer.self.impl;
import java.util.ArrayList;
import java.util.List;
import com.alvin.observer.self.Observer;
import com.alvin.observer.self.Subject;
public class WeatherData implements Subject {
private List<Observer> observers = new ArrayList<Observer>();
private float temperature;
private float humidity;
private float pressure;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int index = observers.indexOf(o);
if(index > 0){
observers.remove(index);
}
}
@Override
public void notifyObservers() {
for(Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementChanged(){
notifyObservers();
}
public void setMeasurementChanged(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
public float getTemperature(){
return temperature;
}
public float getHumidity(){
return humidity;
}
public float getPressure(){
return pressure;
}
}
package com.alvin.observer.self.impl;
import com.alvin.observer.self.DisplayElement;
import com.alvin.observer.self.Observer;
import com.alvin.observer.self.Subject;
public class CurrentConditionDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
private Subject subject;
public CurrentConditionDisplay(Subject subject){
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void display() {
System.out.println("CurrentConditionDisplay " + "temperature :" + temperature
+"humidity :" + humidity + "pressure :" + pressure);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
package com.alvin.observer.self.impl;
import com.alvin.observer.self.DisplayElement;
import com.alvin.observer.self.Observer;
import com.alvin.observer.self.Subject;
public class ForecastDisplay implements DisplayElement, Observer {
private float temperature;
private float humidity;
private float pressure;
private Subject subject;
public ForecastDisplay(Subject subject){
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
@Override
public void display() {
System.out.println("ForecastDisplay " + "temperature :" + temperature
+"humidity :" + humidity + "pressure :" + pressure);
}
}
package com.alvin.observer.self.impl;
import com.alvin.observer.self.DisplayElement;
import com.alvin.observer.self.Observer;
import com.alvin.observer.self.Subject;
public class StatisticDisplay implements DisplayElement, Observer {
private float temperature;
private float humidity;
private float pressure;
private Subject subject;
public StatisticDisplay(Subject subject){
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
@Override
public void display() {
System.out.println("StatisticDisplay " + "temperature :" + temperature
+"humidity :" + humidity + "pressure :" + pressure);
}
}
package com.alvin.observer;
import com.alvin.observer.self.Observer;
import com.alvin.observer.self.Subject;
import com.alvin.observer.self.impl.CurrentConditionDisplay;
import com.alvin.observer.self.impl.ForecastDisplay;
import com.alvin.observer.self.impl.StatisticDisplay;
import com.alvin.observer.self.impl.WeatherData;
public class RunSelf {
public static void main(String[] args) {
Subject subject = new WeatherData();
Observer observer1 = new CurrentConditionDisplay(subject);
Observer observer2 = new ForecastDisplay(subject);
Observer observer3 = new StatisticDisplay(subject);
subject.setMeasurementChanged(1, 1, 1);
subject.setMeasurementChanged(2, 2, 2);
subject.setMeasurementChanged(3, 3, 3);
}
}
输出结果:
CurrentConditionDisplay temperature :1.0humidity :1.0pressure :1.0
ForecastDisplay temperature :1.0humidity :1.0pressure :1.0
StatisticDisplay temperature :1.0humidity :1.0pressure :1.0
CurrentConditionDisplay temperature :2.0humidity :2.0pressure :2.0
ForecastDisplay temperature :2.0humidity :2.0pressure :2.0
StatisticDisplay temperature :2.0humidity :2.0pressure :2.0
CurrentConditionDisplay temperature :3.0humidity :3.0pressure :3.0
ForecastDisplay temperature :3.0humidity :3.0pressure :3.0
StatisticDisplay temperature :3.0humidity :3.0pressure :3.0
使用java内置的观察者模式实现气象站需求
代码实现
package com.alvin.observer.sys;
import java.util.Observable;
public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;
public void measurementChanged(){
setChanged();
notifyObservers();
}
public void setMeasurementChanged(float temperature,float humidity,float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
package com.alvin.observer.sys;
import java.util.Observable;
import java.util.Observer;
public class GeneralDisplay implements Observer {
private float temperature;
private float humidity;
private float pressure;
public GeneralDisplay(Observable o) {
o.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
WeatherData data = null;
if(o instanceof WeatherData){
data = (WeatherData)o;
this.temperature = data.getTemperature();
this.humidity = data.getHumidity();
this.pressure = data.getPressure();
display();
}
}
public void display() {
System.out.println("GeneralDisplay " + "temperature = " +temperature
+ "humidity" + humidity + "pressure" + pressure);
}
}
package com.alvin.observer.sys;
import java.util.Observable;
import java.util.Observer;
public class StatisticDisplay implements Observer {
private float temperature;
private float humidity;
private float pressure;
public StatisticDisplay(Observable o) {
o.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
WeatherData data = null;
if(o instanceof WeatherData){
data = (WeatherData)o;
this.temperature = data.getTemperature();
this.humidity = data.getHumidity();
this.pressure = data.getPressure();
display();
}
}
public void display() {
System.out.println("StatisticDisplay " + "temperature = " +temperature
+ "humidity" + humidity + "pressure" + pressure);
}
}
package com.alvin.observer.sys;
import java.util.Observer;
public class RunSys {
public static void main(String[] args) {
WeatherData subject = new WeatherData();
Observer observer1 = new GeneralDisplay(subject);
Observer observer2 = new StatisticDisplay(subject);
subject.setMeasurementChanged(1, 1, 1);
subject.setMeasurementChanged(2, 2, 2);
subject.setMeasurementChanged(3, 3, 3);
}
}
输出结果:
StatisticDisplay temperature = 1.0humidity1.0pressure1.0
GeneralDisplay temperature = 1.0humidity1.0pressure1.0
StatisticDisplay temperature = 2.0humidity2.0pressure2.0
GeneralDisplay temperature = 2.0humidity2.0pressure2.0
StatisticDisplay temperature = 3.0humidity3.0pressure3.0
GeneralDisplay temperature = 3.0humidity3.0pressure3.0
GeneralDisplay temperature = 1.0humidity1.0pressure1.0
StatisticDisplay temperature = 2.0humidity2.0pressure2.0
GeneralDisplay temperature = 2.0humidity2.0pressure2.0
StatisticDisplay temperature = 3.0humidity3.0pressure3.0
GeneralDisplay temperature = 3.0humidity3.0pressure3.0