观察者模式适合的场景:

  • 其作用在于:别的类 在某些数据有所变动的时候 能够及时的获取到这个变动;
  • 适合一对多的依赖关系。

观察者模式:优雅的众星拱月 - 图1
本文以此UML实例为例。


Subject

Subject的意义:
  • 用来存储变动的数据和数据的变动;
  • 由上,使得变动的数据能及时的传达到需要的类(即Observer);
  • Subject在传达数据时,不需要关心接收者是否需要这次变动;
  • Subject在传达数据时,不要关系接收者的情况。
    Subject必须提供的能力:
  1. ArrayList<Observer> obArray; //装载观察者(或称数据接收者)的容器;
  2. addObserver(Observer ob); //提供向 容器 添加observer的方法,此方法将在observer里调用;
  3. notifyObservers(); //当数据变动时,在这里调用observer们提供的方法,使得在这里提醒observer们数据有所改动;
  4. removeObserver(Observer ob); //提供从容器中删除这个 观察者 的方法,此方法将在observer里被调用。

    接收数据的Observer

    Observer需要提供的能力:
  5. update(); //在subject中调用notifyObservers()时,实质上就是调用observer.update()来达到通知和更新observer数据的效果;

  6. Subject subject; //存储subject,便于接下来的操作。

具体的Subject实例:

  1. 使用接口,规定subject们的行为:

    1. public interface Subject {
    2. public int addObserver(Observer Observer);
    3. public int removeObserver(Observer Observer);
    4. public int notifyObservers();
    5. }
  2. 具体的subject实例:

    1. public class WeatherData implements Subject {
    2. private ArrayList<Observer> observersList; //提供存储observer的容器
    3. float temperature;
    4. float humidity; //湿度
    5. float pressure;
    6. public WeatherData() {
    7. observersList = new ArrayList<Observer>();
    8. }
    9. @Override
    10. public int addObserver(Observer observer) { //提供给observer的加入自己这个容器的方法
    11. observersList.add(observer);
    12. return 0;
    13. }
    14. @Override
    15. public int removeObserver(Observer observer) { //提供给observer的从容器中删除自己的方法
    16. observersList.remove(observer);
    17. return 0;
    18. }
    19. @Override
    20. public int notifyObservers() { //提醒observer们,数据有变动。在此处,observer的数据也将被更新
    21. for (Iterator<Observer> it = observersList.iterator(); it.hasNext(); ) {
    22. it.next().update(temperature, humidity, pressure);
    23. }
    24. return 0;
    25. }
    26. private void DataChanged() {
    27. notifyObservers();
    28. }
    29. public void setData(float temp, float hum, float pre) {
    30. temperature = temp;
    31. humidity = hum;
    32. pressure = pre;
    33. DataChanged();
    34. }
    35. }

    具体的Observer实例:

  3. 同样是先使用接口,规定observer们的行为:

    1. public interface Observer {
    2. public void update(float temp, float hum, float press);
    3. }
  4. 具体的observer实例:

    1. public class StatisticsDisplay implements Observer, DisplayBroad { //DisplayBroad是另外规定 显示 动作的接口,在此不体现
    2. float temperature;
    3. float humidity; //湿度
    4. float pressure;
    5. Subject weatherData; //存储具体的构造器
    6. public StatisticsDisplay(Subject weatherData) { //本实例的具体subject将从构造器中传入
    7. this.weatherData = weatherData;
    8. weatherData.addObserver(this);
    9. }
    10. @Override
    11. public void update(float temp, float hum, float pre) { //提供给subject中notify()操作的方法。在此实例中,被通知即进行数据更新
    12. temperature = temp;
    13. humidity = hum;
    14. pressure = pre;
    15. display();
    16. }
    17. @Override
    18. public int display() { //其他行为
    19. System.out.println("Statistics:" + temperature + "," + humidity + "," + pressure);
    20. return 1;
    21. }
    22. }