• 观察者模式的概念和用法
  • 发布于 2个月前
  • 290 热度
    0 评论
  • 黄月英
  • 0 粉丝 57 篇博客
  •   
概念
定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在转换状态时,会通知所有的观察者对象,使它们能够自动更新自己

结构
抽象观察者角色:定义了一个更新接口,使主题角色更改通知时更新自己
具体观察者角色:实现抽象观察者角色定义的更新接口,以便在主题角色更改通知时更新自己的状态
抽象主题角色:抽象主题角色将所有观察者对象保存在一个集合中,每个主题都可以拥有若干数量的观察者。抽象主题角色提供一个接口,可以增加和删除观察者角色
具体主题角色:具体主题角色将有关状态存入具体观察者对象,在具体主题角色的内部状态发生改变时,给所有注册过的观察者发送通知

示例
目标:如气象站检测温度,当发现有变化时,通知跟其合作的天气预报台更新温度

抽象观察者角色
package 设计模式.行为型模式.观察者模式;
/**
 * 抽象观察者角色
 */
public abstract class Observer {

  /**
   * 更新
   */
  abstract void change(double temperature);

}
具体观察者角色一
package 设计模式.行为型模式.观察者模式;

/**
 * 彩虹天气:具体主题角色
 */
public class RainbowWeather extends Observer {

  /**
   * 更新
   */
  @Override
  void change(double temperature) {
    System.out.println("彩虹天气:当前温度为" + temperature);
  }

}
具体观察者角色二
package 设计模式.行为型模式.观察者模式;

/**
 * 堆代码 duidaima.com
 * 墨迹天气:具体主题角色
 */
public class MojiWeather extends Observer {

  /**
   * 更新
   */
  @Override
  void change(double temperature) {
    System.out.println("墨迹天气:当前温度为" + temperature);
  }

}
抽象主题角色
package 设计模式.行为型模式.观察者模式;

/**
 * 抽象主题角色
 */
public abstract class Subject {

  /**
   * 注册观察者
   */
  abstract void registerObserver(Observer user);

  /**
   * 移除观察者
   */
  abstract void removeObserver(Observer user);

  /**
   * 通知观察者
   */
  abstract void notifyObserver();

}
具体主题角色
package 设计模式.行为型模式.观察者模式;

import java.util.ArrayList;
import java.util.List;

/**
 * 气象站:具体主题角色
 */
public class WeatherStation extends Subject {

  /** 保存的观察者角色对象 */
  private List<Observer> userList = new ArrayList<>();

  /** 温度 */
  private double temperature;

  /**
   * 设置温度
   */
  void setTemperature(double temperature) {
    this.temperature = temperature;
  }

  /**
   * 注册观察者
   */
  @Override
  void registerObserver(Observer user) {
    userList.add(user);
  }

  /**
   * 移除观察者
   */
  @Override
  void removeObserver(Observer user) {
    userList.remove(user);
  }

  /**
   * 通知观察者
   */
  @Override
  void notifyObserver() {
    for (Observer user : userList) {
      user.change(this.temperature);
    }
  }

}
测试类
package 设计模式.行为型模式.观察者模式;

/**
 * 测试类
 */
public class Demo {

  public static void main(String[] args) {
    // 创建气象台的主题角色对象
    WeatherStation subject = new WeatherStation();

    // 添加观察者角色对象
    subject.registerObserver(new RainbowWeather());
    subject.registerObserver(new MojiWeather());

    // 更新温度
    subject.setTemperature(31.2);
    // 通知观察者更新
    subject.notifyObserver();
  }

}
优缺点
优点
1.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系
2.被观察者发送通知、所有注册的观察者都会收到信息【可以实现广播机制】

缺点
1.如果观察者非常多,那么所有的观察者收到被观察者发送的通知会耗时
2.如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,导致系统崩溃

应用场景
1.对象之间存在一对多关系,一个对象的状态发生改变会影响其他对象时,可以使用观察者模式
2.当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时,可以使用观察者模式

用户评论