Java设计模式(十五)之行为型模式:观察者模式

Java设计模式(十五)之行为型模式:观察者模式

一、定义:

观察者模式中,观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。   在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。

观察者模式又称为发布-订阅模式。

UML结构图:

Java设计模式(十五)之行为型模式:观察者模式

该模式包含四个角色:

(1)Subject:抽象主题(被观察者)。他把所有对观察者对戏的引用保存在一个集合里,每一个主题都可以有多个观察者。被观察者提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

(2)Observer:抽象观察者。为所有的具体观察者定义一个接口,在得到主题的通知时能够及时的更新自己

(3)ConcreteSubject:具体主题。将有关状态存入具体观察者对象。在具体主题发生改变时,给所有的观察者发出通知。

(4)ConcreteObserver:具体观察者。实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

 

二、实现观察者模式:

情景是这样的:在气象观测站中,它能够追踪目前的天气状况,包括温度、适度、气压。需要实现一个布告板,能够分别显示目前的状态,气象统计和简单的预报。当气象站中获取最新的测量数据时,三种布告板必须实时更新。

        下面是这个案例的设计图:

Java设计模式(十五)之行为型模式:观察者模式

编码实现:

主题接口   Subject.java

public interface Subject {
	/**
	 * 注册观察者
	 * @param observer
	 */
	public void registerObserver(Observer observer);
	
	/**
	 * 删除观察者
	 * @param observer
	 */
	public void removeOberver(Observer observer);
	
	/**
	 * 当主题状态发生改变时,这个方法需要被调用,以通知所有观察者
	 */
	public void notifyObserver();
}

观察者接口  Observer.java

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

布告板显示接口 DisplayElement.java

public interface DisplayElement {
	public void display();
}

WeatherData实现主题接口 WeatherData.java

public class WeatherData implements Subject{
	private List<Observer> observers;
	private float tempterature;
	private float pressure;
	private float humidity;
	
	public WeatherData(){
		observers = new ArrayList<Observer>();
	}
	
	@Override
	public void notifyObserver() {
		for(int i = 0; i < observers.size();i++){
			Observer observer = observers.get(i);
			observer.update(tempterature, humidity, pressure);
		}
	}
 
	@Override
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}
 
	@Override
	public void removeOberver(Observer observer) {
		int i = observers.indexOf(observer);
		if(i >= 0){
			observers.remove(i);
		}
	}
 
	/**
	 * 气象站得到更新的观测数据时,通知观察者
	 */
	public void measurementChanged(){
		notifyObserver();
	}
	
	public void setMeasurements(float temperature,float humidity,float pressure){
		this.tempterature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementChanged();
	}
}

布告板  CurrentCondituonDisplay.java

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);      //注册观察者
	}
	
	public void update(float temp, float humidity, float pressure) {
		this.temperature = temp;
		this.humidity = humidity;
		display();
	}
 
	@Override
	public void display() {
		System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity");
	}
 
}

测试程序  WeatherStation

public class WeatherStation {
 
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		
		CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
	
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(82, 70, 29.2f);
		weatherData.setMeasurements(78, 78, 40.4f);
	}
}

运行结果:

Java设计模式(十五)之行为型模式:观察者模式

 

 

三、观察者模式小结:

1、观察者模式的两种模式:
观察者模式在关于目标角色、观察者角色通信的具体实现中,有两个版本:

(1)一种情况便是目标角色在发生变化后,仅仅告诉观察者角色“我变化了”,观察者角色如果想要知道具体的变化细节,则就要自己从目标角色的接口中得到。这种模式被很形象的称为:拉模式——就是说变化的信息是观察者角色主动从目标角中“拉”出来的。

(2)还有一种方法,那就是我目标角色“服务一条龙”,通知你发生变化的同时,通过一个参数将变化的细节传递到观察者角色中去。这就是“推模式”——管你要不要,先给你啦。

这两种模式的使用,取决于系统设计时的需要。如果目标角色比较复杂,并且观察者角色进行更新时必须得到一些具体变化的信息,则“推模式”比较合适。如果目标角色比较简单,则“拉模式”就很合适啦。

2、优点:

(1)当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。主题所知道只是一个具体的观察者列表,每一个具体观察者都符合一个抽象观察者的接口。主题并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。

(2)观察者模式支持“广播通信”。主题会向所有的观察者发出通知。

(3)观察者模式符合“开闭原则”的要求。

3、缺点:

(1)如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

(2)如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

(3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

4、适用场所:

(1)一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将二者封装在独立的对象中使它们可以各自独立地改变和复用。

(2)一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。

(3)一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。换言之, 你不希望这些对象是紧密耦合的。

 

原博客链接:

https://blog.csdn.net/chenssy/article/details/8955696

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100068.html原文链接:https://javaforall.net

(0)
上一篇 2021年4月9日 上午11:05
下一篇 2021年4月9日 下午12:00


相关推荐

  • BMP格式详解

    BMP格式详解BMP 全称 Bitmap 是 Windows 操作系统中的标准图像文件格式 可以分成两类 设备相关位图 DDB 和设备无关位图 DIB 使用非常广 它采用位映射存储格式 除了图像深度可选以外 不采用其他任何压缩 因此 BMP 文件所占用的空间很大 BMP 文件的图像深度可选 lbit 4bit 8bit 及 24bit BMP 文件存储数据时 图像的扫描方式是按从左到右 从下到上的顺序 由于 BMP 文件格式是 Wi

    2026年3月20日
    3
  • 今天发现一个JQ插件库网站

    今天发现一个JQ插件库网站http www jq22 com 备忘一下

    2026年3月17日
    2
  • idea intellij 查看接口被哪些类实现「建议收藏」

    idea intellij 查看接口被哪些类实现「建议收藏」点击接口左侧的绿色圆点出现的列表就是该接口被实现的类

    2022年8月15日
    8
  • volatile关键字及其作用「建议收藏」

    volatile关键字及其作用「建议收藏」概述:本文主要介绍Java语言中的volatile关键字,内容涵盖volatile的保证内存可见性、禁止指令重排等。

    2022年5月31日
    32
  • Android快速转战Kotlin教程「建议收藏」

    Android快速转战Kotlin教程「建议收藏」前言kotlin是啥?这里就不用多说了,想必看这篇文章的童鞋肯定是有所了解的。那么这篇文章你可以收获什么?答:本文主要通过本人如何从java转战到kotlin并应用在实际项目中的个人经历,给大家提供一些学习思路、学习方法以及一些学习资料和个人总结。前提:你的项目(包含个人项目)即将开始用到kotlin(没有项目作为依托你会缺少十足的动力,而且缺少应用场景乘热打铁那也…

    2022年5月25日
    32
  • Haar特征与积分图

    Haar特征与积分图Haar 特征与积分图 1 Adaboost 方法的引入 1 1Boosting 方法的提出和发展 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 在了解 Adaboost 方法之前 先了解一下 Boosting 方法 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 回答一个是与否的问题 随机猜测可以获得 50 的正确率 如果一种方法能获得比随机猜测稍微高一点的正确率 则就可以称该得到这个方法的过程为弱学习 如果一个方法可以显著提高猜测的正确率

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号