1 / 30

观察者模式

观察者模式. 观察者模式. 气象监控应用系统概观 系统有三个部分: 气象站 — 获取实际气象数据的物理设备 气象数据对象 — 跟踪气象站的数据,并更新布告板 布告板 — 向用户显示当前的目前状况 ( 温度、湿度、气压 ) 或气象统计或天气预报. Weather 对象知道如何跟物理气象站联系,取得新的数据。我们的工作是建立一个应用, 利用 Weather 对象的数据 , 更新三个布告板 。. 有三个布告板,将来可能需要增加新的布告板。. 气象站送来的数据类 (WeatherData). 我们的工作是实现 measurementsChanged() ,

ria-rose
Download Presentation

观察者模式

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 观察者模式

  2. 观察者模式 气象监控应用系统概观 系统有三个部分: 气象站— 获取实际气象数据的物理设备 气象数据对象— 跟踪气象站的数据,并更新布告板 布告板 — 向用户显示当前的目前状况(温度、湿度、气压)或气象统计或天气预报

  3. Weather对象知道如何跟物理气象站联系,取得新的数据。我们的工作是建立一个应用,利用Weather对象的数据,更新三个布告板。Weather对象知道如何跟物理气象站联系,取得新的数据。我们的工作是建立一个应用,利用Weather对象的数据,更新三个布告板。

  4. 有三个布告板,将来可能需要增加新的布告板。有三个布告板,将来可能需要增加新的布告板。

  5. 气象站送来的数据类(WeatherData) 我们的工作是实现 measurementsChanged(), 好让它更新目前状况、 气象统计和天气预报的 显示布告板。 不在乎此方法是如何调用的,只在乎它被调用了。

  6. 一个可能的实现 public class WeatherData { // 实例变量声明 public void measurementsChanged() { float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionsDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); } // 其它WeatherData方法 } 传入最新的测量值,调用布告板的更新显 示。 取得最近的测量值。 更新布告板。

  7. 我们的实现的缺陷在哪里? 针对具体的实现编码。如果不修改程序,我们就无法 增加或删除其它显示成分。 … currentConditionsDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); … 针对具体实现编程,导致增加或删除布告板时,必须修改程序。

  8. 会会观察者模式

  9. 观察者模式也称为发布-订阅模式 • 报社的业务就是出版报纸 • 向某家报社订阅报纸,只要他们有新报纸出版,就会给 • 你送来。只要你是他们的用户,你就会一直收到新报纸 • 当你不想再看报纸的时候,取消订阅,他们就不会再送 • 新报纸 • 只要报社还在运营,就会一直有人(或单位)向他们订 • 阅报纸或取消订阅报纸

  10. 观察者模式定义

  11. 观察者模式类图 实现观察者模式的一种方法。

  12. 松耦合的威力 当两个对象是松耦合的,它们彼此之间能够交互,但是 相互了解很少。 观察者模式提供了主题和观察者之间的松耦合设计。 因为主题只知道观察者实现了某个接口(即Observer接口), 主题不需要知道具体观察者是谁、作了些什么或其它任何 细节。要增加新的观察者或删除观察者,主题不会受到任 何影响,不必修改主题代码。 可以独立地复用主题和观察者,它们之间互不影响, 即是松耦合的。

  13. 松耦合的威力(续) 由于松耦合设计使得对象间的依赖最小化,所以, 我们能够创建柔性的OO系统,应对变化的情况,因为 对象之间的依赖降到了最低。

  14. 设计气象站 右边三个布告板也应该有一个“主题”指针指向WeatherData对象,本图未画出来。

  15. 实现气象站 public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } public interface Observer { public void update(float temp, float humidity, float pressure); } public interface DisplayElement { public void display(); } 需要观察者作为参数。

  16. 实现气象数据的Subject接口 public class WeatherData implements Subject { private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList(); } ArrayList记录观察者。

  17. 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 notifyObservers() { for (int i = 0; i < observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } }

  18. public void measurementsChanged() { notifyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } // other WeatherData methods here }

  19. 实现显示 public class CurrentConditionsDisplay implements Observer, DisplayElement { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity"); } } weatherData供注册或取消注册之用。 另外两个布告板的实现非常类似。

  20. 为气象站提供动力 public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } } 模拟新的气象测量。

  21. 运行程序

  22. Java内置的观察者模式 • java.util包(package)内包含了最基本的Observable类与 • Observer接口,这与我们subject接口和Observer接口很 • 相似。 • Java GUI。例如,JButton可以增加或删除倾听者 • (listener),例如,ActionListener能倾听在按钮上发生的 • 动作。这些倾听者就是观察者。 • JavaBeans。

  23. 实例代码分析 public class Secretary { //前台秘书类 private ArrayList observers; // 同事列表 private string action; public Secretary () { observers = new ArrayList(); } public void attach(StockObserver observer) // 增加 { observers.add(observer) } public void notify() { // 通知 for (int i=0; i<observers.size(); i++) { StockObserver observer = (StockObserver) observers.get(i) observer. update(); } } public void secretaryAction(string action) { // 发生新的事件 this.action = action; notify( ); } … }

  24. public class StockObserver // 看股票同事类 { private string name; private Secretary sub; public StockObserver(string name, Secretary sub) { this.name = name; this.sub = sub; sub.attach(name); } public void update( ) { System.out.println(“关闭股票,继续工作!"); } … } public class client { //客户端程序 public static void main(String[] args) { // 前台小姐 Secretary qiantai = new Secretary ( ); // 看股票同事 StockObserver tongshi1 = new StockObserver(“张山”); StockObserver tongshi2 = new StockObserver(“李四”); // 发现老板回来 qiantai.secretaryAction(“老板回来了”); } }

More Related