设计模式学习(二)之观察者模式

本文介绍了观察者模式,以报纸订阅为例阐述其实现原理。通过观察者模式,当气象站获取新的测量数据时,会自动通知各布告板进行更新。文章提供了使用自定义和Java内置观察者模式的代码实现,展示了如何创建和管理订阅关系,实现松耦合的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报纸和杂志的订阅是怎么一回事?
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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值