`
sasipa90
  • 浏览: 14589 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
最近访客 更多访客>>
社区版块
存档分类
最新评论

The observer Pattern

阅读更多
The observer Pattern
=================

   Most of time we will be in need of making some systems which work like the news paper which means that we will have one object which will need to give periodically information to the client. So, the Observer Pattern = Publishers (Subject) + Subscribers (Observer).
   To deal with this form of design we have two choices. The first one is to write by ourselves interfaces to represent the subject and the observer class the second one is to use API’s tools which are respectively java.util.observable class to represent subject and java.util.observer interface to represent observer. But this last one has a dark side: Observable is a class and don’t even have an interface and we know that in design pattern it is advised to use interface as the principle “Favor composition over inheritance” said. Worse is that the method setChanged() is a protected one which means that we can’t call the method unless we has subclassed Observable.

   Here we will use code to understand more about it, in the first example we created our own Subject and Observer interface, in the second one we used one’s given by API. This example is about a weather station which will get data from the subject and display the data. Here we can remember that a weather station needs to update its data each time there is changes.

Example 1:

package com.observer.weather;


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

package com.observer.weather;

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


package com.observer.weather;

import java.util.ArrayList;

/*
 * This class will be used to deal with observes
 */
public class WeatherData implements Subject {
	
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData(){
		observers = new ArrayList();
	}

	public void registerObserver(Observer o) {
		observers.add(o);
	}

	public void removeObserver(Observer o) {
		int i = observers.indexOf(o);
		if(i>= 0){
			observers.remove(i);
		}
	}

	public void notifyObserver() {
		for(int i = 0; i<observers.size(); i++){
			Observer observer = (Observer)observers.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();
	}
}
package com.observer.weather;

public interface DisplayElement {
	public void display();
}


package com.observer.weather;

public class CurrentConditionsDisplay implements Observer{
	private float temperature;
	private float humidity;
	private float pressure;
	private Subject weatherData;
	
	public CurrentConditionsDisplay(Subject weatherData){
		this.weatherData = weatherData;
		weatherData.registerObserver(this);
	}
	
	@Override
	public void update(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		display();
	}
	
	public void display(){
		System.out.println("The current conditions: "+temperature+
					" F degrees, "+humidity+" % humidity and "+pressure+" of pressure ");
	}
	

}
package com.observer.weather;

public class CurrentConditionsDisplay implements Observer{
	private float temperature;
	private float humidity;
	private float pressure;
	private Subject weatherData;
	
	public CurrentConditionsDisplay(Subject weatherData){
		this.weatherData = weatherData;
		weatherData.registerObserver(this);
	}
	
	@Override
	public void update(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		display();
	}
	
	public void display(){
		System.out.println("The current conditions: "+temperature+
					" F degrees, "+humidity+" % humidity and "+pressure+" of pressure ");
	}
	

}


package com.observer.weather;

public class WeatherStation {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		HeatIndexDisplay heatdisplay = new HeatIndexDisplay(weatherData);
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(82, 7, 29.2f);
		weatherData.setMeasurements(78, 90, 29.2f);
	}
}

Example 2:

package com.observer.weather2;

import java.util.Observable;

/*
 * This class will be the subject of the weather station
 */
public class WeatherData extends Observable{
	
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData(){}
	
	/*
	 * Will be called whenever data change
	 */
	public void measurementsChanged(){
		setChanged();
		notifyObservers();
	}
	
	public void setMesurements(float temperature, float humidity, float pressure){
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}

	public float getTemperature() {
		return temperature;
	}

	public void setTemperature(float temperature) {
		this.temperature = temperature;
	}

	public float getHumidity() {
		return humidity;
	}

	public void setHumidity(float humidity) {
		this.humidity = humidity;
	}

	public float getPressure() {
		return pressure;
	}

	public void setPressure(float pressure) {
		this.pressure = pressure;
	}

}


package com.observer.weather2;

public interface DisplayElement {
	public void display();
}


package com.observer.weather2;

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

public class CurrentConditionsDisplay implements Observer,DisplayElement{
	
	private Observable observable;
	private float temperature;
	private float humidity;
	
	public CurrentConditionsDisplay(Observable observable){
		this.observable = observable;
		observable.addObserver(this);
	}
	
	@Override
	public void display() {
		System.out.println("The current conditions: "+temperature+" F degrees, "+humidity+" % humidity");
	}

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

package com.observer.weather2;

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

public class ForecastDisplay implements Observer, DisplayElement {
	private float temperature;
	private float humidity;
	private float currentPressure = 29.2f;
	private float lastPressure;
	private Observable observable;
	
	public ForecastDisplay(Observable observable){
		this.observable = observable;
		observable.addObserver(this);
	}

	public void display() {
		System.out.println("The current conditions: "+temperature+" F degrees, "+humidity+" % humidity");
	}

	public void update(Observable o, Object arg) {
		if(o instanceof WeatherData){
			WeatherData weatherData = (WeatherData)o;
			lastPressure = currentPressure;
			currentPressure = weatherData.getPressure();
			temperature = weatherData.getTemperature();
			humidity = weatherData.getHumidity();
			display();
		}
	}

}

package com.observer.weather2;

public class WeatherStation {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
		weatherData.setMesurements(80, 65, 30.4f);
		weatherData.setMesurements(82, 7, 29.2f);
		weatherData.setMesurements(78, 90, 29.2f);
	}
}

Conclusion:
----------------

In conclusion we learnt a new principle which is: “Strive for loosely coupled design between object that interact”. This principle will make our program more flexible that means for instance if we need to add a new Display of the weather data or need to change how one display tool could display those data.
Remember that the Observer pattern defines a one- to- many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
分享到:
评论

相关推荐

    QT做的经典2048游戏

    The core is decoupled from the GUI using the observer pattern, so it is easy to pull the code, extract the core and then build a new GUI around it. 1. Download and install Qt ...

    matlab开发-Observerpattern

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它允许一个对象,当其状态发生改变时,能够自动通知所有依赖它的对象。在MATLAB中实现观察者模式,可以帮助我们构建灵活、可扩展的代码结构,特别是在...

    Ajax for Web Application Developers(Ajax网站开发)

    The Observer Pattern Pattern Overview Creating an Error-Handling Object Using the Error-Handling Object Chapter 17. Data Reflection Pattern An Overview Creating the Pattern Chapter 18. ...

    Design Patterns in Modern C++-Apress(2018)

    Readers should be aware that comprehensive solutions to certain problems (e.g., the Observer pattern) typically result in overengineering, that is, the creation of structures that are far more ...

    2048小游戏

    The core is decoupled from the GUI using the observer pattern, so it is easy to pull the code, extract the core and then build a new GUI around it. Screenshot -- ![Alt text]...

    Beyond.the.C++ - Standard.Library.An.Introduction.to.Boost

    the Observer pattern) with Boost.Signals &lt;br&gt;The Boost libraries are proving so useful that many of them are planned for inclusion in the next version of the C++ Standard Library. Get your head ...

    Beyond the C++ Standard Library An Introduction to Boost

    the Observer pattern) with Boost.Signals &lt;br&gt;The Boost libraries are proving so useful that many of them are planned for inclusion in the next version of the C++ Standard Library. Get your head ...

    JAVA面试题目 JAVA面试题目一览表

    For instance, using the Singleton pattern ensures there's only one instance of a class, reducing resource consumption, while the Observer pattern allows for efficient event handling in a decoupled ...

    高清彩版 jQuery.Design.Patterns

    #### The Observer Pattern **观察者模式** 是一种行为设计模式,它允许你定义一个订阅机制,可以在对象事件发生时通知多个“观察者”对象。 - **介绍观察者模式:** - 观察者模式的核心在于一个主题(Subject)...

    函数式反应编程Scala.Rx.zip

    Scala.Rx 是一个 Scala 的函数式反应编程的库,基于 FRP 和 Deprecating the Observer Pattern 理论的实现. 简单例子: import rx._ val a = Var(1); val b = Var(2) val c = Rx{ a() b() } println(c()) // 3 a...

    the code of Design Pattern

    在本资源“the code of Design Pattern”中,我们很可能会找到有关如何在C++编程语言中实现各种设计模式的代码示例。 设计模式分为三类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例(Singleton...

    Programming.in.the.Large.with.Design.Patterns

    Each pattern is introduced with a non-technical example or story that illustrates the pattern concept. The details are described with Java code examples and UML diagrams. Each pattern description ...

    .NET Design Patterns [Kindle Edition]

    you will be able to convincingly leverage these design patterns (factory pattern, builder pattern, prototype pattern, adapter pattern, facade pattern, decorator pattern, observer pattern and so on) ...

    Swift DesignPattern

    print("Observer received the update.") } } ``` 5. **装饰者模式(Decorator)**:装饰者模式允许在不改变对象类的情况下动态地给对象添加新的行为或责任。Swift中,通过继承和组合,我们可以实现对已有对象的...

Global site tag (gtag.js) - Google Analytics