观察者模式定义了对象之间的一对多依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新
Now we start Oberver Patern
if we have been selected to build our next generation Internet -based Weather Monitoring Station!~ it can tracks current weather conditions (temperature, humidity, and barometric pressure).
we need to create an application that initially provides three display elements:current conditions, weather statistics and a simple forecast , all updated in real time as the WeatherData object acquires the most recent measurements.
Further, this is an expandable weather station, so we should release an API so that other developers can write their own weather displays and plug them right in .
Taking ower first implementation possibility to it :
Since above disadvantages . we think how newspaper or magazine subscriptions work:
- A newspaper publisher goes into business and begins publishing newspapers.
- You have subscribe to a particular publisher ,and every time there’s a new edition it gets delivered to you. As long as you remain a subscriber, you’ll get newspapers.
- Once you have unsubscribe when you don’t want papers anymore , and they stopped to be delivered.
While the publisher remains in business , people , hotel, airlines and other businesses constantly subscribe and unsubscribe to the newspaper
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.
Subject
package observer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
Observer
package observer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
CurrentConditionsDisplay
package observer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherDate;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherDate = 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 = temperature;
this.humidity = humidity;
display();
}
}
WeatherData
package observer;
import java.util.ArrayList;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public class WeatherData implements Subject {
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
if(observers.indexOf(o) >= 0) {
observers.remove(observers.indexOf(o));
}
}
@Override
public void notifyObservers() {
for(Object o : observers) {
((Observer)o).update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
DisplayElement
package observer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public interface DisplayElement {
public void display();
}
WeatherStation
package observer;
/**
* CopyRright (c)2014-2016 Haerbin Hearglobal Co.,Ltd
* Project: idoc-main
* Comments:
* Author:cbam
* Create Date:2016/11/17
* Modified By:
* Modified Date:
* Modified Reason:
*/
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentConditionsDisplay =
new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(90f,100.02f,22f);
// there we can create our own weather display
// so it's expandable , users can add or remove
// as many display elements as they want to the application.
weatherData.removeObserver(currentConditionsDisplay);
weatherData.setMeasurements(90f,100.02f,22f);
}
}
So far we’ve rolled our own code for the Observer Pattern , but Java has built-in support in several of this APIs. it’s quite similar to our Subject and Observer interface.