`
不平凡的人
  • 浏览: 35446 次
  • 性别: Icon_minigender_1
  • 来自: 嘉峪关
社区版块
存档分类
最新评论

观察者模式

 
阅读更多

本文从以下方法阐述观察者模式

一、定义观察者

二、观察者模式示例

三、推模型与拉模型

四、JAVA内置观察者

五、总结

 

一、定义观察者模式

 

 1、定义

       观察者模式为对象的行为模式,主要定义一种一对多的对象关系(观察者:主题对象=1:n)。让多个观察者对象去监听同一个主题对象Subject(被依赖的对象),当主题对象的内容状态发生变化时,会通知所有注册过的观察者对象,促使观察者对象的内容更新。

 

2、观察者模式的结构图

(1)以订报纸业务为例:

          报社:Subject(主题类,被依赖的对象)

          订阅者:Observer 观察者(依赖报社)

(2)报社Subject:负责,登记注册,通知,移除观察者的工作

(3)订阅者Observer:负责接收报社通知拿报纸



 

二、观察者模式示例

 

1、主题类接口

 

package net.oschina.design.observer.interfac;

/**
 * 观察者模式中的主类,被依赖的类
 * 
 * @author Freedom
 * 
 */
public interface Subject {
	/*
	 * 注册观察者
	 */
	public void registObserver(Observer o);

	// 移除观察者
	public void removeObserver(Observer o);

	// 通知观察者
	public void notifyObserver();
}
 

 

2、观察者接口

 

package net.oschina.design.observer.interfac;

/**
 * 观察者模式中 依赖的类
 * 
 * @author Freedom
 * 
 */
public interface Observer {

	/*
	 * 实时更新subject类中的数据
	 */
	public void updateDate(float temp, float press);

}
 

 

3、主题类的实现

 

package net.oschina.design.observer.interfac.impl;

import java.util.ArrayList;
import java.util.List;

import net.oschina.design.observer.interfac.Observer;
import net.oschina.design.observer.interfac.Subject;

/**
 * 气象台主类
 * 
 * @author Freedom
 * 
 */
public class WeatherData implements Subject {

	private final List<Observer> observerList; // 模拟注册保存观察者数据的链表

	private float temp;// 气温

	private float press;// 气压

	public WeatherData() {
		observerList = new ArrayList<Observer>(5);
	}

	@Override
	public void registObserver(Observer o) {
		if (null != o) {
			observerList.add(o);
		}
	}

	@Override
	public void removeObserver(Observer o) {
		if (null != o) {
			observerList.remove(o);
		}
	}

	// 通知观察者
	@Override
	public void notifyObserver() {

		if (null != observerList && !observerList.isEmpty()) {
			for (Observer o : observerList) {
				// 观察者实时显示天气信息
				o.updateDate(this.getTemp(), this.getPress());
			}
		}
	}

	// 设置参数
	public void setWeather(float temp, float press) {
		this.temp = temp;
		this.press = press;

		// 气象台更新了数据后,通知观察者
		this.notifyObserver();
	}

	/*
	 * setter /getter
	 */
	public float getTemp() {
		return temp;
	}

	public void setTemp(float temp) {
		this.temp = temp;
	}

	public float getPress() {
		return press;
	}

	public void setPress(float press) {
		this.press = press;
	}

}
 

 

4、观察者类的实现

 

package net.oschina.design.observer.interfac.impl;

import net.oschina.design.observer.interfac.Observer;

/**
 * 显示当前气温的观察者
 * 
 * @author Freedom
 * 
 */
public class CurrentWeatherObserver implements Observer {

	/*
	 * 观察者实时更新天气(non-Javadoc)
	 * 
	 * @see
	 * net.oschina.design.observer.interfac.Observer#updateDate(net.oschina.
	 * design.observer.interfac.Subject)
	 */
	@Override
	public void updateDate(float temp, float press) {
		this.display(temp, press);
	}

	public void display(float temp, float press) {
		System.out.println("今天天气****气温****" + temp);
		System.out.println("今天天气****气压****" + press);
	}

}

 

5、运行代码

 

package net.oschina.design.observer;

import net.oschina.design.observer.interfac.impl.CurrentWeatherObserver;
import net.oschina.design.observer.interfac.impl.WeatherData;

public class MainObserver {

	public static void main(String[] args) {
		// subject
		WeatherData w = new WeatherData();
		// observer
		CurrentWeatherObserver cur = new CurrentWeatherObserver();

		w.registObserver(cur);
		w.setWeather(11.1f, 213.111111f);

	}

}
 


 

上述代码运行分析:先实例化一个主题类对象,然后实例化一个观察者类的对象,之后主题对象中注册观察者对象。当主类对象中数据改变时,就通知观察者对象,观察者对象获取到主题对象发来的信息后,及时更新自己的信息并显示。

 

三、推模型与拉模型

  在观察者模式中,又分为推模型和拉模型两种方式。

1、推模型

  主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。

 

2、拉模型

  主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。

 

3、两种模型比较

     (1)推模型是假定主题对象知道观察者需要的数据(个人愚见,主题的主动行为);而拉模型是主题对象不知道观察者具体需要什么数据,直接将主题对象本身传递给观察者(主题的被动行为所需数据要观察者根据需要自己获取),让观察者自己去按需要取值。

     (2)推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。

 

四、JAVA内置观察者

 

1、主题类:继承Observable类

 

package net.oschina.design.observer.innerobserver.subject;

import java.util.Observable;

/**
 * java内置观察者,主类
 * 
 * @author Freedom
 * 
 */
public class WeatherData extends Observable {

	private float temp;// 温度
	private float press;// 气压

	/*
	 * 主类数据变化通知观察者
	 */
	public void change() {
		// 必须要调用setChanged方法
		this.setChanged();
		// 调用通知方法,调用通知方法,拉模型将主题的所有数据传递给观察者
		this.notifyObservers(new Data(this.getTemp(), this.getPress()));
	}

	/**
	 * 设置主类中将要通知给观察者的数据
	 */
	public void setData(float temp, float press) {
		this.temp = temp;
		this.press = press;

		// 调用通知方法
		change();
	}

	public float getTemp() {
		return temp;
	}

	public float getPress() {
		return press;
	}

	/**
	 * 保存主类数据的内置对象
	 * 
	 * @author Freedom
	 * 
	 */
	public class Data {

		private float temp;// 温度
		private float press;// 气压

		public Data(float temp, float press) {
			this.temp = temp;
			this.press = press;
		}

		public Data() {
		}

		public float getTemp() {
			return temp;
		}

		public float getPress() {
			return press;
		}

	}

}
 

 

2、观察者类实现java.util.Observer接口

 

package net.oschina.design.observer.innerobserver.observer;

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

import net.oschina.design.observer.innerobserver.subject.WeatherData.Data;

/**
 * 当前天气的观察者
 * 
 * @author Freedom
 * 
 */
public class CurrentWeather implements Observer {

	private float temp;
	private float press;

	@Override
	public void update(Observable o, Object arg) {
		this.temp = ((Data) (arg)).getTemp();
		this.press = ((Data) (arg)).getPress();

		display();

	}

	// 显示天气
	public void display() {
		System.out.println("当天天气[温度]:" + temp + "  [气压]:" + press);
	}

}
 

 

3、运行类

 

package net.oschina.design.observer.innerobserver.main;

import net.oschina.design.observer.innerobserver.observer.CurrentWeather;
import net.oschina.design.observer.innerobserver.subject.WeatherData;

public class MainInnerObserver {

	public static void main(String[] args) {

		WeatherData w = new WeatherData();
		CurrentWeather c = new CurrentWeather();

		w.addObserver(c);// 注册观察者
		w.setData(11.1f, 22.5f);

	}

}
 

 

 

4、查看源码内置观察者的方法如下



 

5、注意事项:

①主类通知观察者对象之前要调用 setChanged()方法,然后再调用notifyObservers()通知方法;

解释:直接看源码一目了然



 



 

 

四、总结

 

1、观察者模式主要为了解决:对象之间存在1:N依赖关系的情况,被依赖的一方为主题类,依赖的一方为观察者类;

2、观察者模式又叫发布-订阅(Publish/Subscribe)模式模型-视图(Model/View)模式源-监听器(Source/Listener)模式从属者(Dependents)模式;

3、观察者模式,可以有效的降低对象之间的耦合度,比如说:当主题类停止工作时,观察者最多是接受不到数据,依然可以继续工作

4、java内置观察者,主题类为一个实体类Observable类而非接口,调用通知方法前先调用setChanged方法;内置观察者主题类中注册观察者时维护了一个集合为Vector

 

 

如上,内容可能还有遗漏欠缺,还请高端玩家斧正留言.....

  • 大小: 10.3 KB
  • 大小: 10.9 KB
  • 大小: 10.1 KB
  • 大小: 27.9 KB
  • 大小: 52.7 KB
  • 大小: 12.4 KB
分享到:
评论

相关推荐

    设计模式实现——观察者模式

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现发布-订阅...

    java 设计模式 观察者模式 简单实例 包括测试test类

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动或者发布...

    Qt设计模式之观察者模式

    本篇文章将深入探讨Qt中的观察者模式(Observer Pattern),这是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心...

    java观察者模式观察者模式

    观察者模式是设计模式中的一种行为模式,它在Java编程中有着广泛的应用。该模式的主要目的是定义对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式也被...

    设计模式-观察者模式(讲解及其实现代码)

    观察者模式,也被称为发布-订阅模式,是软件设计中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在分布式系统、事件驱动...

    Java内置观察者模式

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它允许一个对象,当其状态发生改变时,能够自动通知所有依赖它的其他对象。在Java中,这种模式已经被内置到语言核心,使得开发者可以轻松地实现事件驱动...

    设计模式--观察者模式java例子

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    观察者模式模版和例子

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于实现事件驱动的系统或者...

    设计模式之观察者模式Java实现

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    运用MVC模式及观察者模式的java小程序

    在这个名为“运用MVC模式及观察者模式的java小程序”的项目中,我们重点探讨了两种经典的设计模式:Model-View-Controller(MVC)模式和Observer(观察者)模式。这两种模式在JavaWeb开发中扮演着至关重要的角色。 ...

    iOS 设计模式 观察者模式

    观察者模式,也被称为发布-订阅(Publish-Subscribe)模式,是软件设计中的一种行为模式。在iOS开发中,它是一种让多个对象监听或订阅某一个主题对象的状态变化,并在状态变化时自动收到通知的方式。这种模式使得...

    56丨观察者模式(上):详解各种应用场景下观察者模式的不同实现方式1

    观察者模式详解 观察者模式(Observer Design Pattern)是行为型设计模式的一种,主要解决的是“类或对象之间的交互”问题。它定义了一个一对多的依赖关系,当一个对象的状态改变时,所有依赖的对象都会自动收到...

    观察者模式编写的股票分析程序

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在这个"股票分析程序"中,我们很显然看到它利用了这种模式来实时更新股票...

    设计模式之观察者模式

    观察者模式是面向对象设计中的一种经典模式,它在软件工程中扮演着重要的角色,用于实现对象间的松耦合。这种模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并...

    观察者模式源码

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于事件驱动的系统或者实时...

    观察者模式代码

    观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Java或其他面向对象语言中,这种模式通常用于实现事件处理或发布/订阅系统。在给定的“观察者...

    观察者模式练习

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    Unity3D设计模式之观察者模式

    ### Unity3D设计模式之观察者模式 #### 观察者模式概述 观察者模式(Observer Pattern)是一种软件设计模式,属于行为型模式之一。它定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它...

    观察者模式的一个应用

    ### 观察者模式概述与应用 #### 一、观察者模式定义 观察者模式是一种常用的软件设计模式,主要用于处理对象间的依赖关系。在这种模式下,一个对象(称为“主题”或“被观察者”)负责维护一组依赖于它的对象...

Global site tag (gtag.js) - Google Analytics