现在的位置: 首页 > 综合 > 正文

设计模式之观察者模式(5)

2018年03月18日 ⁄ 综合 ⁄ 共 5432字 ⁄ 字号 评论关闭

Design Principle

Strive for loosely coupled designs between objects that interact.

Loosely coupled designs allow us to build flexible OO systems that can handle change because they minimize the interdependency between objects.

Observer Pattern



The Subject contains the state and controls it. The observers use the state. There are many observers and they rely on the Subject to tell them when its state changes.

For the Subject to send notification

1) You first call a method(like setChanged()) to signify that the state has changed in your object.

2) Then, call notifyObservers() method (which calls observers update() method).

For the Observer to receive notifications

It implements the update method.



The class work flow:

1) Observers regist: Observers use Subject's  registerObserver() method to regist

2) Subject send notification: Subject calls a method(like setChanged()) to signify that the state has changed in his object, then call notifyObservers() method (which calls observers update() method).

Example:

Subjct is the WeatherProvider, when the weather's temperature changed, it notices Observers who are a group of people who has buy its service(here we named these poeple are ClientA,ClientB)


WeatherProvider

public class WeatherProvider implements Subject {
	private HashSet<Observer> observers;
	private float temperature;

	// -------------------------------------------------
	public WeatherProvider() { // constructor
		observers = new HashSet<Observer>();
	}

	// -------------------------------------------------
	public void registObserver(Observer o) {
		observers.add(o);
	}

	// -------------------------------------------------
	public void removeObserver(Observer o) {
		observers.remove(o);
	}

	// -------------------------------------------------
	public void notifyObservers() {
		for(Observer o: observers){
			o.update(temperature);
		}//end for
	}
	
	// -------------------------------------------------
	public void temperatureChanged(){
		notifyObservers();
	} //end temperatureChanged()
	
	// -------------------------------------------------
    public void setTemperature(float temperature){
    	this.temperature=temperature;
    	temperatureChanged();
    } //end setTemperature()
    
    //other weather methods here
}

ClientA and ClientB

public class ClientA implements Observer {
	private float temperature;
	private Subject wetherProvider;
	
	// -------------------------------------------------
	public ClientA(Subject wetherProvider){
		this.wetherProvider=wetherProvider;
		wetherProvider.registObserver(this);
	}
	// -------------------------------------------------
	public void update(float temperature) {
		this.temperature = temperature;
		display();
	} // end update()
	// -------------------------------------------------
	// output the current temperature when you want to know it
	public void display() {
         System.out.println(ClientA.class.getSimpleName()+": current temperature is "+temperature);
	} // end display()
}

public class ClientB implements Observer {
	private float temperature;
	private Subject wetherProvider;
	
	// -------------------------------------------------
	public ClientB(Subject wetherProvider){
		this.wetherProvider=wetherProvider;
		wetherProvider.registObserver(this);
	}
	// -------------------------------------------------
	public void update(float temperature) {
		this.temperature = temperature;
		display();
	} // end update()
	// -------------------------------------------------
	// output the current temperature when you want to know it
	public void display() {
         System.out.println(ClientA.class.getSimpleName()+": current temperature is "+temperature);
	} // end display()
}

Test App

public class WeatherApp {
	public static void main(String[] args) {
		//subject
		WeatherProvider WeatherProvider=new WeatherProvider();
		//observers
		Observer clientA=new ClientA(WeatherProvider);
		Observer clientB=new ClientB(WeatherProvider);
        
		//notify current temperature
		WeatherProvider.setTemperature(80);	
	}//end main()
}

Run Result

Using Java's built-in Observer Pattern

Java has built-in support in several of its API. The most general is the Observer interface and the Observable class in the java.util an java.lang package. These are quite similar to our Subject and Observer interface.

With Java's built-in support, all you have to do is extend Observable and tell it when to notify the Observers. The API does the rest for you.





In either case, you need to call setChanged() for notifications to work.

clearChanged() sets the changed state back to false,

hasChaged() tells you the current state of the changed flag.

The above example is modified like this:

/* We don't need to keep track of our observers anymore,
or manage their registration and removal (the superclass will handle that),
so we're removed the code for register and notify.
*/
public class WeatherProvider extends Observable {
	private float temperature;

	// -------------------------------------------------
	public WeatherProvider() { // constructor
//		observers = new HashSet<Observer>();
	}
	// -------------------------------------------------
	public void temperatureChanged(){
		setChanged();
		notifyObservers();
	} //end temperatureChanged()
	
	// -------------------------------------------------
    public void setTemperature(float temperature){
    	this.temperature=temperature;
    	temperatureChanged();
    } //end setTemperature()
    
    public float getTemperature(){
    	return temperature;
    }
    //other weather methods here
}


public class ClientA implements java.util.Observer {
	private float temperature;
	private Observable observable;
	
	// -------------------------------------------------
	public ClientA(Observable observable){
		this.observable=observable;
		observable.addObserver(this);
	}
	// -------------------------------------------------
	public void update(Observable o, Object arg) {
		WeatherProvider weatherProvider=(WeatherProvider)o;
		this.temperature=weatherProvider.getTemperature();
		display();
	}
	// -------------------------------------------------
	// output the current temperature when you want to know it
	public void display() {
         System.out.println(ClientA.class.getSimpleName()+": current temperature is "+temperature);
	} // end display()
}

Applicaiton 

Application of Observer Pattern


抱歉!评论已关闭.