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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值