观察者模式

本文介绍观察者模式,一种用于解耦交互对象的设计模式。通过定义一对多的关系,当主题对象的状态发生变化时,所有观察者都能自动更新。文章包括模式的概念、角色关系、实例代码及Java内置观察者模式的应用。

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

一、概述

观察者模式有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己.

二、问题解决

观察者模式提供了一种对象设计,让主题和观察者之间松耦合(松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低 ).

三、模式的角色关系


Subject:它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者,可以注册和删除观察者对象.

Observer:为所有的具体观察者定义一个接口,在得到主题通知时更新自己.

四、实例展示UML图


五、Demo展示

1、Subject接口

package cn.design.observer;

public interface Subject {
	
	void registerObserver(Observer observer);
	void removeObserver(Observer observer);
	void notifyObserver();

}

2、Subject的实现类,WeatherData

package cn.design.observer;

import java.util.ArrayList;

public class WeatherData implements Subject{
	
	private ArrayList<Observer> obserList=null;
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData() {
		obserList=new ArrayList<>();
	}

	@Override
	public void registerObserver(Observer observer) {
		obserList.add(observer);
		
	}

	@Override
	public void removeObserver(Observer observer) {
		
		int index=obserList.indexOf(observer);
		if (-1!=index) {
			obserList.remove(index);
		}
	}

	@Override
	public void notifyObserver() {
		
		if (null!=obserList&&obserList.size()>0) {
			
			for (Observer observer : obserList) {
				observer.update(temperature, humidity, pressure);
			}
			
		}
		
//		for (int i = 0; i < obserList.size(); i++) {
//			Observer observer=obserList.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();
	
	}

}
3、Observer接口

package cn.design.observer;

public interface Observer {
	
	void update(float temp,float humidity,float pressure);

}
4、DisplayElement接口,测试显示输出结果

package cn.design.observer;

public interface DisplayElement {
	
	void display();

}
5、ObServer的实现类CurrentConditionsDisplay,可以定义更多的观察者,eg:ForecastDisplay、StatisticsDisplay

package cn.design.observer;

public class CurrentConditionsDisplay implements Observer ,DisplayElement {

	private float temperature;
	private float humidity;
	private Subject weatherData;
	
	
	public CurrentConditionsDisplay(Subject weatherData) {
		this.weatherData=weatherData;
		weatherData.registerObserver(this);
	}
	
	@Override
	public void display() {
		System.out.println("Current temperature is "+temperature+"degree "+" and humidity is %"+humidity);
		
	}


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

}
6、测试类

package cn.design.observer;

public class WeatherTest {
	
	public static void main(String[] args) {
		
		WeatherData weatherData=new WeatherData();
		CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherData);
		weatherData.setMeasurements(80, 64, 30.4f);
		
		
	}

}
六、使用Java内置的观察者模式实现上面demo(Observable、Observer)

1、UML图


2、Observable的实现类WeatherData

package cn.java.observer;

import java.util.Observable;

public class WeatherData extends Observable{
	
//	private ArrayList<Observer> obserList=null;
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData() {
//		obserList=new ArrayList<>();
	}
	
//	@Override
//	public synchronized void addObserver(Observer o) {
//		obserList.add(o);
//	}
	
//	@Override
//	public synchronized void deleteObserver(Observer o) {
//		
//		int index=obserList.indexOf(o);
//		if (-1!=index) {
//			obserList.remove(index);
//		}
//	}
	
	
	
    public void setMeasurements(float temperature,float humidity,float pressure) {
		
		this.temperature=temperature;
		this.humidity=humidity;
		this.pressure=pressure;
		measurementsChanged();
	
	}

    public void measurementsChanged() {
    	
	     setChanged();
	     notifyObservers();
	
     }
    
    public float getTemperature() {
    	
    	return temperature;

	}
	
    public float getHumidity() {
    	
    	return humidity;

	}
	
    public float getPressure() {
    	
    	return pressure;

	}
	

}
3、Observer的实现类CurrentConditionsDisplay,可以有多个Observer,eg:StatisticsDisplay、etc

package cn.java.observer;

import java.util.Observable;
import java.util.Observer;

public class CurrentConditionsDisplay implements Observer{
	
	private float temperature;
	private float humidity;
	private Observable weatherData;
	
	public CurrentConditionsDisplay(Observable observable) {
		this.weatherData=observable;
		weatherData.addObserver(this);
		
	}
	

	@Override
	public void update(Observable o, Object arg) {
		
		if (o instanceof WeatherData) {
			WeatherData weatherData=(WeatherData) o;
			temperature=weatherData.getTemperature();
			humidity=weatherData.getHumidity();
			display();
			
		}
		
	}
	
	public void display() {
		System.out.println("Current temperature is "+temperature+"degree "+" and humidity is %"+humidity);
		
	}

}
4、测试类

package cn.java.observer;

public class WeatherTest {
	
	public static void main(String[] args) {
		
		WeatherData weatherData=new WeatherData();
		CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherData);
		weatherData.setMeasurements(80, 64, 30.4f);
		
		
	}

}
七、总结

观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体,从而使得各自的变化都不会影响另一边的变化.
设计目的:为交互对象之间的送耦合而设计.

注:文章实例来源于Head First设计模式一书,此书生动有趣,推荐对模式有兴趣的朋友可以去看下,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值