一、观察者模式定义

1.观察者模式又称发布-订阅模式,定义一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听,使得每当主题对象状态变化时,所有依赖于它的对象都会得到通知并被自动更新。属于行为型模式

2.观察者模式的核心是将观察者和被观察者解耦,以类似于消息/广播发送的机制联动两者,使被观察者的变动能通知到感兴趣的观察者们,从而做出相应的响应

3.观察者模式的应用场景:

  A.当一个抽象模型包含两个方面内容,其中一个方面依赖于另一个方面

  B.其他一个或多个对象的变化依赖于另一个对象的变化

  C.实现类似广播机制的功能,无需知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播

  D.多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知

二、观察者模式示例

1.观察者模式一般包含4种角色:

  A.抽象主题(Subject):指被观察的对象(Observable)。该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法

  B.具体主题(ConcreteSubject):具体被观察者,当其内状态变化时,会通知已注册的观察者

  C.抽象观察者(Observer):定义了响应通知的更新方法

  D.具体观察者(ConcreteObserver):在得到状态更新时,会自动做出响应

2.代码示例

 1 //抽象主题者
 2 public interface ISubject<E> {
 3     boolean attach(IObserver<E> observer);
 4 
 5     boolean detach(IObserver<E> observer);
 6 
 7     void notify(E event);
 8 }
 9 
10 //具体主题者
11 public class ConcreteSubject<E> implements ISubject<E> {
12     private List<IObserver<E>> observers = new ArrayList<IObserver<E>>();
13 
14     public boolean attach(IObserver<E> observer) {
15         return !this.observers.contains(observer) && this.observers.add(observer);
16     }
17 
18     public boolean detach(IObserver<E> observer) {
19         return this.observers.remove(observer);
20     }
21 
22     public void notify(E event) {
23         for (IObserver<E> observer : this.observers) {
24             observer.update(event);
25         }
26     }
27 }
28 
29 //抽象观察者
30 public interface IObserver<E> {
31     void update(E event);
32 }
33 
34 //具体观察者
35 public class ConcreteObserver<E> implements IObserver<E> {
36     public void update(E event) {
37         System.out.println("receive event: " + event);
38     }
39 }
40 
41 public class Test {
42 
43     public static void main(String[] args) {
44         // 被观察者
45         ISubject<String> observable = new ConcreteSubject<String>();
46         // 观察者
47         IObserver<String> observer = new ConcreteObserver<String>();
48         // 注册
49         observable.attach(observer);
50         // 通知
51         observable.notify("hello");
52     }
53 
54 }

3.观察者模式优缺点

  A.优点

    a.观察者和被观察者是松耦合(抽象耦合)的,符合依赖倒置原则

    b.分离了表示层(观察者)和数据逻辑层(被观察者),并建立了一套触发机制,使得数据的变化可以影响到多个表示层上

    c.实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者触发事件时,只有感兴趣的观察者可以接收到通知

  B.缺点

    a.如果观察者数量过多,则事件通知会耗时较长

    b.事件通知呈线性关系,如果其中一个观察者处理事件卡壳儿,会影响后续的观察者接收该事件

    c.如果观察者和被观察者之间存在循环依赖,则可能造成两者之间的循环调用,导致系统崩溃