观察者(Observer)模式

观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,需要在 B 变化的一瞬间做出反应。举个例子,新闻里喜闻乐见的警察抓小偷,警察需要在小偷伸手作案的时候实施抓捕。在这个例子里,警察是观察者,小偷是被观察者,警察需要时刻盯着小偷的一举一动,才能保证不会漏过任何瞬间。程序的观察者模式和这种真正的『观察』略有不同,观察者不需要时刻盯着被观察者(例如 A 不需要每过 2ms 就检查一次 B 的状态),而是采用注册(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我需要你的某某状态,你要在它变化的时候通知我。 典型的使用场景就是图形化界面编程时为按钮设置监听器。比如,开发者添加了一个按钮(Button),希望用户用鼠标点击此按钮后会弹出警告框。在这个场景中,用户点击按钮就是一个事件(event),可是用户何时会点击按钮确实不确定的,这怎么办呢?通用的做法是给按钮添加一个监听方法,这个方法负责监听用户的点击行为,也就是观察者,一旦点击事件发生,观察者会产生一个警告框。

所以,观察者模式又被称为发布-订阅(publish-subscribe)模式。

观察者模式产生的动机,将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类紧密耦合,因为这样降低了它们的可重用性。

注意,对于同一个被观察者,可以有多个观察者,好比一个小偷可以被多个警察同时监控,一旦小偷作案,监控的警察都会行动起来进行抓捕:

适用性:

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

书籍推荐