`

设计模式-观察者模式

阅读更多

转载请注明本文出自1124117571的博客(www.1124117571.iteye.com),谢谢支持!

观察者模式(Observer)行为型模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

 

OO原则:为了交互对象之间的松耦合设计而努力

当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题观察者之间松耦合。具体过程,假如我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。

 

下面拿气象站的例子来说明观察者模式

 

下面是气象站例子的UML图

                               
WeatherStation的UML图

 

 下面是UML图中各个成分的具体代码:

 

气象站的布告板:

 

/*
 * 气象站的布告板
 */
public interface Subject {
	public void registerObserver(Observer o);	// 用来注册观察者
	public void removeObserver(Observer o);		// 用来移除观察者
	public void notifyObservers();	// 当主题状态改变时,这个方法会被调用以通知所有的观察者
}

 

 

观察者接口:

 

/*
 * 所有的气象组件都实现此观察者接口
 * 所有的观察者都必须实现update方法,以实现观察者接口
 */
public interface Observer {
	public void update(float temp,float humidity,float pressure);
}

 

 

当布告板需要显示时,调用此方法

 

/*
 * 当布告板需要显示时,调用此方法
 */
public interface DisplayElement {
	public void display();
}

 

 

WeatherData对象(追踪来自气象站的数据,并更新布告板)

 

/*
 * WeatherData对象(追踪来自气象站的数据,并更新布告板)
 */
public class WeatherData implements Subject {
	private ArrayList<Observer> observers;
	private float temperature;	// 温度值
	private float humidity;		// 湿度值
	private float pressure;		// 气压值
	
	public WeatherData(){
		observers = new ArrayList<Observer>();
	}
	
	// =====================Subject接口的实现================================
	public void registerObserver(Observer o){	// 当注册观察者时,我们只需要把它加到ArrayList的后面即可
		observers.add(o);
	}
	
	public void removeObserver(Observer o){
		int i = observers.indexOf(o);
		if(i > 0){	// 说明ArrayList中存在该观察者
			observers.remove(i);	
		}
	}
	
	public void notifyObservers(){
		for(int i = 0;i < observers.size();i++){
			Observer observer = (Observer)observers.get(i);
			// 通过观察者的接口向观察者发送通知
			observer.update(temperature, humidity, pressure);
		}
	}
	// =================================================================
	
	// 当从气象站得到更新观测值时,我们通知观察者
	public void messurementsChanges(){
		notifyObservers();
	}
	
	public void setMeasurements(float temperature,float humidity,float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		messurementsChanges();
	}
	
	// WeatherData的其他方法
}

 

 

建立布告板

 

/*
 * 此布告板实现了Observer接口,所以可以从WeatherData对象中获得改变
 * 规定了所有的布告板都必须实现DisplayElement接口
 */
public class CurrentConditionDisplay implements Observer, DisplayElement {

	private float temperature;
	private float humidity;
	private Subject weatherData;

	public CurrentConditionDisplay(Subject weatherData) {
		this.weatherData = weatherData; // 需要weatherData对象作为注册用
		weatherData.registerObserver(this);
	}

	// 把最近的温度和湿度显示出来
	@Override
	public void display() {
		System.out.println("Current conditions:" + temperature + "F degrees and " + humidity + "% humidity");
	}

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

 

 

 

测试程序WeatherStation

/**
 * 测试程序WeatherStation
 * @author asus
 *
 */
public class WeatherStation {
	public static void main(String[] args){
		WeatherData weatherData = new WeatherData();
		CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData);
		// 模拟新的气象测量
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(82, 70, 29.2f);
		weatherData.setMeasurements(78, 90, 29.2f);
	}
}

 

测试结果



 

 

以上都是通过自己的努力从无到有地完成了观察者模式,但是Java API有内置的观察者模式。

java.util包内包含最基本的Observer接口和Observable类

Observable类追踪所有观察者并通知他们



 

 

 Java内置的观察者模式如何运作:

如何把对象变成观察者?

答:实现观察者接口(java.util.Observer),然后调用任何Observer对象的addObserver方法,不想再当观察者时,调用deleteObserver()方法就可以了。

 

观察者如何送出通知?

答:1.首先需要李勇扩展java.util.Observer接口产生“可观察者”类。

   2.先调用setChanged()方法,标记状态已经改变的事实。

   3.然后调用两种notifyObservers()方法中的一个。

  

setChanged()方法的用处?

答:setChanged()方法用来标记状态已经改变的事实,好让notifyObservers()知道当它被调用时应该更新观察者,如果调用notifyObservers()之前没有先调用setChanged(),观察者就不会被通知。

 

 

Obserser类内部伪代码

 

setChanged(){
	changed = true;	// setChanged()方法把changed标志设为true
}

// notifyObservers只会在changed标为true时通知观察者
notifyObservers(Object args){
	if(changed()){
		for every Observer on the list{
			can udpate(this,args);
		}
		changed = false;	// 在通知观察者之后,把changed标志设置为false
	}

 

 

下面就进行改造,改造成使用Java内置的观察者模式

 

1.把WeatherData改成使用java.util.Observable

 

public class WeatherData extends Observable{
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData(){}
	
	public void measurementsChanged(){
		setChanged();	// 在调用notifyObservers()之前,要先调用setChanged()来指示状态已经改变
		notifyObservers();	// 没有调用notifyObservers()传送数据对象,我们采用的做法是"拉"
	}
	
	//=======================================================
	// 观察者会利用下面这些方法取得WeatherData对象的状态
	public void setMeasurements(float temperature,float humidity,float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
	
	public float getTemperature(){
		return temperature;
	}
	
	public float getHumidity(){
		return humidity;
	}
	
	public float getPressure(){
		return pressure;
	}
	//=======================================================

	// WeatherData的其他方法
}

 

注意:

继承Observable表明该类是发送者(消息提供者)。

继承Observer表明该类是接收者(观察者)。

 

 

2.重做CurrentConditionDisplay

public class CurrentConditionDisplay implements Observer, DisplayElement {

	Observable observable;
	private float temperature;
	private float humidity;

	public CurrentConditionDisplay(Observable observable) {
		this.observable = observable;
		observable.addObserver(this);
	}

	@Override
	public void display() {
		System.out.println("Current conditions: " + temperature + "F degress and " + humidity + "% humidity");
	}

	@Override
	public void update(Observable obs, Object arg) {
		if (obs instanceof WeatherData) {
			WeatherData weatherData = (WeatherData) obs;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			display();
		}
	}

}

 

 

测试结果:



 

 

Java内置的观察者模式的缺点:

1.Observable是一个类,从而限制了Observable的潜力,因为没有Observable接口,我们无法建立自己的实现和Java内置的Observer API配套使用。

2.违反了OO设计原则:多用组合,少用继承,因此除非你继承自Observable,否则将无法创建Observable实例并组合到我的对象中。

 

 

 

 

  • 大小: 123 KB
  • 大小: 106.3 KB
  • 大小: 15.1 KB
  • 大小: 15.6 KB
1
1
分享到:
评论

相关推荐

    跟我一起学 设计模式-观察者模式

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

    设计模式-观察者模式-作业-observer.zip

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

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

    总结来说,观察者模式是一种重要的设计模式,它允许对象在状态改变时自动通知其他对象,从而降低了系统各部分之间的耦合度,提高了代码的灵活性和可扩展性。在实际项目中,正确使用观察者模式可以有效地管理组件间的...

    Java 设计模式-观察者模式(Observer)

    结合微信公众号讲解观察者模式,生动形象,关键是上手快啊

    java常用设计模式-观察者模式

    观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。该模式适用于需要在对象间建立动态的、松散耦合的关系的...

    设计模式-观察者模式(读书笔记)

    观察者模式是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这个模式在很多场景下都有广泛的应用,例如事件处理、...

    设计模式-观察者模式 基于MFC实现的消息监听机制

    基于MFC实现的消息监听机制,利用了设计模式中的观察者模式,对线程间的同步做了优化,以及可以选择消息的发送类型:同步或异步发送。对于监听者而言在注册监听的同时可以选择监听的消息类型,避免了发送者发送的...

    JAVA-设计模式-行为型模式-观察者模式

    JAVA-设计模式-行为型模式-观察者模式

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

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

    Android设计模式--观察者模式DEMO

    Android设计模式--观察者模式DEMO 观察者模式是一个使用频率非常高的模式,他最常用的地方是GUI系统和订阅-发布系统。 该模式的最重要的作用就是解耦,使观察者和被观察者之间依赖尽可能小,甚至好无依赖。

    设计模式-观察者

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

    java设计模式-观察者模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...

    C++设计模式--观察者模式 demo

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它在C++中的应用广泛且实用。这种模式的核心思想是“主体”(Subject)与“观察者”(Observer)之间的松耦合关系,允许一个对象(即主体)的状态...

    c++设计模式-行为型模式-观察者模式

    c++设计模式-行为型模式-观察者模式;qt工程;c++简单源码; 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式...

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

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

    设计模式--观察者 c++版本

    观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心思想是主体(Subject)与观察者(Observer)之间的...

    java设计模式-观察者 小案例

    观察者模式(Observer Pattern)是其中一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 在Java中,观察者模式通常通过`java.util....

Global site tag (gtag.js) - Google Analytics