观察者模式 1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。 2)定义观察者模式 3)实现观察者模式 3)松耦合的威力 4)实现气象站 5)观察者模式的“推(push)”和“拉(pull)” 6)Java内置的观察者模式 7)小结


 观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

一个错误的实现:

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

在这个错误的实现中:

  • 我们是针对具体实现编程,而非针对接口
  • 对于每个新的布告板,我们都得修改代码
  • 我们无法再运行时动态地增加或删除布告板
  • 我们尚未封装改变的部分

 

观察者模式与报纸的订阅非常相似:

  1. 报社的业务就是出版报纸
  2. 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸
  3. 当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来
  4. 只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或取消报纸

观察者模式=出版者+订阅者

只是在观察者模式中,出版者改称为“主题”(Subject),订阅者改称为“观察者”(Observer)

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

2)定义观察者模式


观察者模式定义了一系列对象之间的一对多关系。

当一个对象改变状态,其他依赖者都会受到通知。

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

实现观察者模式的方法不止一种,但是以包含Subject与Observer接口的类设计的做法最常见。

3)实现观察者模式


因为布告板的差异性,我们需要一个共同的接口,让布告板的类(可能不一样)都去实现相同的接口,好让WeatherData对象能够知道如何把观测值送给它们。

定义观察者模式类图:

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

设计气象站:

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

3)松耦合的威力


当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。

观察者模式提供了一种对象设计,让主题和观察者之间松耦合。

为什么呢?

关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。

任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代旧的观察者,主题不会受到任何影响。同样的,也可以在任何时候删除某些观察者。

有新类型的观察者出现时,主题的代码不需要修改。加入我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。

我们可以独立地复用主题或观察者。如果我们在其他地方需要使用主题或观察者,也可以轻易地复用,因为二者并非紧耦合。

改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以*地改变他们。

松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

4)实现气象站


观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

 观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

5)观察者模式的“推(push)”和“拉(pull)”


到此为止,我们已经从无到有的完成了观察者模式。

仔细看我们实现的观察者模式会发现,所有的信息都是由主题“推(push)”给观察者的;

还有一种观察者模式是通过观察者从主题那边“拉(pull)”过来的,当然这需要主题设置相关的getter()方法。

6)Java内置的观察者模式


java.util包(package)内包含最基本的Observer接口与Observerable,这和我们的Subject接口与Observer接口很相似。Observer接口与Observerable类使用上更方便,因为许多功能都已经事先准备好了,你甚至可以使用推(push)或拉(pull)的方式传送数据。

这是修改后的气象站OO设计:

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

观察者模式
1)首先,我们要实现一个气温显示系统,有三个布告板需要相同的更新数据(温度、湿度、气压),由一个WeatherData类提供更新数据,要求每当数据更新时,要通知到三个布告板。最后还要有一个可扩展的第四个布告板,供其他开发人员建立定制的布告板。
2)定义观察者模式
3)实现观察者模式
3)松耦合的威力
4)实现气象站
5)观察者模式的“推(push)”和“拉(pull)”
6)Java内置的观察者模式
7)小结

7)小结


OO基础:

  • 抽象
  • 封装
  • 多态
  • 继承 

 

OO原则:

  • 封装变化
  • 多用组合、少用继承
  • 针对接口编程,不针对实现编程
  • 为交互对象之间的松耦合设计而努力

 

OO模式:

  • 策略模式——定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
  • 观察者模式——在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新

 

要点:

  •  观察者模式定义了对象之间一对多的关系
  • 主题(也就是可观察者)用一个共同接口来更新观察者
  • 观察者和可观察者之间用松耦合方式结合(loosecoupling),可观察者不知道观察者的细节,只知道观察者实现了观察者的接口
  • 使用此模式时,你可以从被观察者处推(push)或拉(pull)数据(然而,推的方式被认为更“正确”)
  • 有多个观察者时,不可依赖特定的通知次序
  • Java有多种观察者模式的实现,包括通用的java.util.Observable
  • 要注意java.util.Observable带来的一些问题
  • 如果有必要的话,可以实现自己的Observable,这并不难
  • Swing大量使用观察者模式,许多GUI框架也是如此
  • 此模式也被应用在许多地方,比如:JavaBeans、BMI

 

  参考书目:《Head First 设计模式》