观察者模式

概述

如果一个对象A的行为依赖另一个对象B的状态,我们可以有两种实现方式:

一种是对象A轮询对象B的状态,根据轮询结果决定自己的行为;另一种是对象B在自身状态发生改变时,主动通知对象A。

不难看出,第二种凡是会比第一种方式效率高,观察者模式即采用第二种方式,观察者模式可以用于事件监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。

类图

 

 主题接口依赖观察者接口,因为要在主题中注册观察者(观察者订阅主题)

 

jdk已经提供了观察者模式

实例

Observer

 1 /**
 2  * 观察者接口
 3  *
 4  * @author zhya
 5  * @date 2018/9/14
 6  **/
 7 public interface IObserver {
 8     /**
 9      * 通知
10      *
11      * @param event
12      */
13     void update(Event event);
14 }

Concrete Observer

 1 /**
 2  * 实际观察者
 3  *
 4  * @author zhangyang
 5  * @date 2018/9/14
 6  **/
 7 public class Observer implements IObserver {
 8     private String name;
 9 
10     public Observer(String name) {
11         this.name = name;
12     }
13 
14     /**
15      * 通知
16      *
17      * @param event
18      */
19     @Override
20     public void update(Event event) {
21         System.out.println(new StringBuffer("observer ").append(this.name).append(" received notification : ").append(event.getMsg()));
22     }
23 }

Subject

 1 /**
 2  * 主题/被观察者接口
 3  *
 4  * @author zhangyang
 5  * @date 2018/9/14
 6  **/
 7 public interface ISubject {
 8     /**
 9      * 注册监听者
10      *
11      * @param observer
12      */
13     void attach(IObserver observer);
14 
15     /**
16      * 注销监听者
17      *
18      * @param observer
19      */
20     void deattach(IObserver observer);
21 
22     /**
23      * 变更通知
24      *
25      * @param event
26      */
27     void inform(Event event);
28 }

Concrete Subject

 1 import java.util.List;
 2 import java.util.Vector;
 3 
 4 /**
 5  * 实际主题/被观察者
 6  *
 7  * @author zhangyang
 8  * @date 2018/9/14
 9  **/
10 public class Subject implements ISubject {
11     private final List<IObserver> observers = new Vector<>();
12 
13     /**
14      * 注册监听者
15      *
16      * @param observer
17      */
18     @Override
19     public void attach(IObserver observer) {
20         if (!observers.contains(observer)) {
21             observers.add(observer);
22         }
23     }
24 
25     /**
26      * 注销监听者
27      *
28      * @param observer
29      */
30     @Override
31     public void deattach(IObserver observer) {
32         observers.remove(observer);
33     }
34 
35     /**
36      * 变更通知
37      *
38      * @param event
39      */
40     @Override
41     public void inform(Event event) {
42         System.err.println("subject has new event : " + event.toString());
43         observers.forEach(observer -> observer.update(event));
44     }
45 }

Main测试类

 1 /**
 2  * 测试类
 3  *
 4  * @author zhya
 5  * @date 2018/9/14
 6  **/
 7 public class Main {
 8     public static void main(String[] args) {
 9         // 监听者
10         IObserver observer1 = new Observer("observer1");
11         IObserver observer2 = new Observer("observer2");
12 
13         // 主题
14         ISubject subject = new Subject();
15 
16         // 注册监听
17         subject.attach(observer1);
18         subject.attach(observer2);
19 
20         // 主题状态变更
21         Event event = new Event("ding ding");
22         subject.inform(event);
23         System.out.println("------------------------------------------");
24 
25         // 注销监听
26         subject.deattach(observer1);
27 
28         // 主题状态变更
29         event = new Event("dang dang");
30         subject.inform(event);
31 
32     }
33 }

执行结果

原文地址:https://www.cnblogs.com/zhya/p/9644652.html