zoukankan      html  css  js  c++  java
  • 观察者模式——HeadFirst 设计模式学习笔记

    观察者模式(Observer Pattern):观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

    推拉两种获取数据方式:

    • 推:可以把数据当做数据对象的方式传给观察者
    • 拉:通过getter方法获取数据

    设计原则:

    • 为了交互对象之间的松耦合而努力,让我们建立有弹性的OO系统

    特点:

    • 观察者模式定义了对象之间的一对多关系
    • 当一个对象的状态改变了,其他的依赖者都会收到通知

    松耦合的威力:

    • 两个对象之间松耦合,他们可以交互,但是不太清楚彼此的细节
    • 观察者模式提供了一种对象设计,让主题和观察者之间松耦合
    • 主题只知道观察者对象实现了某个借口,而不知道观察者具体的细节
    • 我们可以随时添加和删除观察者

    适用性

    1. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
    2. 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
    3. 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。

    举例:

    • 实现一个气象监测系统,此系统的三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)
    • 我们可以通过MeasurementsChanged()方法通知各个布告版
      •  1 public void MeasurementsChanged()
         2  {
         3         float temp = GetTemperature();
         4         float humidity = GetHumidity();
         5         float pressure = GetPressure();
         6     //三个布告版
         7         currentConditionDisplay.update(temp, humidity, pressure);
         8         statisticsDisplay.update(temp, humidity, pressure);
         9         forecastDisplay.update(temp, humidity, pressure);
        10  }
    • 然而布告版的数量是不确定的,可能在某个时刻增加,可能在某个时刻减少,而且种类不同,如果使用如上代码,当布告版变化时代码修改维护量巨大
    • 使用观察者模式修改设计

    代码实现

    1、主题接口

    • 1 public interface Subject {  
      2     public void registerObserver(Observer o);  
      3     public void removeObserver(Observer o);  
      4 public void notifyObservers(); 5 }

    2、观察者接口

    1 public interface Observer {  
    2     public void update(float temp, float humidity, float pressure);  
    3 }

    3、主题实现

     1 public class WeatherData implements Subject {  
     2     private ArrayList observers;  
     3     //temperature、humidity、pressure就是WeatherData的“状态”  
     4     private float temperature;  
     5     private float humidity;  
     6     private float pressure;  
     7       
     8     public WeatherData() {  
     9         observers = new ArrayList();  
    10     }  
    11       
    12     public void registerObserver(Observer o) {  
    13         observers.add(o);  
    14     }  
    15       
    16     public void removeObserver(Observer o) {  
    17         int i = observers.indexOf(o);  
    18         if (i >= 0) {  
    19             observers.remove(i);  
    20         }  
    21     }  
    22       
    23     public void notifyObservers() {  
    24         for (int i = 0; i < observers.size(); i++) {  
    25             Observer observer = (Observer)observers.get(i);  
    26             observer.update(temperature, humidity, pressure);  
    27         }  
    28     }  
    29       
    30     public void measurementsChanged() {  
    31         notifyObservers();  
    32     }  
    33       
    34     public void setMeasurements(float temperature, float humidity, float pressure) {  
    35         this.temperature = temperature;  
    36         this.humidity = humidity;  
    37         this.pressure = pressure;  
    38         measurementsChanged();  
    39     }  
    40       
    41     public float getTemperature() {  
    42         return temperature;  
    43     }  
    44       
    45     public float getHumidity() {  
    46         return humidity;  
    47     }  
    48       
    49     public float getPressure() {  
    50         return pressure;  
    51     }  
    52 }  

    4、观察者实现

     1 public class CurrentConditionsDisplay implements Observer, DisplayElement {  
     2     private float temperature;//温度  
     3     private float humidity;//湿度  
     4     private Subject weatherData;  
     5       
     6     public CurrentConditionsDisplay(Subject weatherData) {  
     7         this.weatherData = weatherData;  
     8         weatherData.registerObserver(this);  
     9     }  
    10     //推数据,这里只使用到了前两个参数  
    11     public void update(float temperature, float humidity, float pressure) {  
    12         this.temperature = temperature;  
    13         this.humidity = humidity;  
    14         display();  
    15     }  
    16       
    17     public void display() {  
    18         System.out.println("Current conditions: " + temperature   
    19             + "F degrees and " + humidity + "% humidity");  
    20     }  
    21 }  

    要点

    1. 观察者模式定义了对象之间一对多的关系。
    2. 主题(也就是可观察者)用一个共同的接口来更新观察者。
    3. 观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
    4. 使用此模式时,你可从被观察者处推或拉数据。
    5. 有多个观察者时,不可以依赖特定的通知次序。
    6. Java有多种观察者模式的实现,包括了通用的java.util.Observable。
    7. 要注意java.util.Observable实现上所带来的一些问题。Swing大量使用观察者模式,许多GUI框架也是如此。
      1. Java内置的观察者模式中Observable是一个类,你必须设计一个类去继承它。如果某类相同时具有Observable类和另一个超类的行为,就无法实现,因为java不支持多继承。
      2. Observable API将setChanged()方法保护了起来,除非继承自Observable类,否则无法创建Observable实例组合到自己的对象中,也违背了面向对象设计的第二个原则:多用组合,少用继承。
    8. 此模式也被应用在许多地方,例如:JavaBeans、RMI。
  • 相关阅读:
    使用express+multer实现node中的图片上传
    利用H5构建地图和获取定位地点
    移动端开发基础 干货分享
    关于angularJS的一些用法
    你好 JSONP !!!!
    CentOS7使用Alien将RPM从DE转换为DEB和DEB转换为RPM包
    [Windows] visio2019破解激活
    python---九九乘法表代码
    HTTP 请求方式: GET和POST的比较
    win10WLAN没有有效的ip配置
  • 原文地址:https://www.cnblogs.com/HectorHou/p/5977905.html
Copyright © 2011-2022 走看看