设计模式---观察者模式

观察者模式:#

  • 参与者:**事件源**(source)、**观察者**(observer/listener)、**事件**(event,可选,如果不想知道时间信息可以不要)
    
  • 1.将事件源上注册多个观察者
    
  • 2.当某种特定条件发生的时候(source的某个场景),事件源将此时的信息包装到event中,逐个调用观察者
    
  • 3.观察者就知晓了事情的发生,并能做出相应(被调用相应方法)
    

image-20200603133906006

优点:#

  • 避免观察者需要持续关注事件源(比如不用开一个线程去不断判断他的状态是否改变)
  • 只需要将事件发生的逻辑提前准备在观察者上,把观察者注册到事件源上
  • 事件发生的时候就能被自动执行

实际应用:#

  • 典型的如UI界面的各种event和listener
    
  • 或者AOP,实际上实现是代理,语义上也是一个观察者模式:当方法执行到这里,就触发AOP绑定的拦截器方法。(只是由代理给实现的)
    
  • 或者Hystrix
    

实现举例#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* 观察者模式:
* - 事件源(source)、观察者(observer/listener)、事件(event,可选,如果不想知道时间信息可以不要)
* - 将事件源上注册多个观察者
* - 当某种特定条件发生的时候(source的某个场景),事件源将此时的信息包装到event中,逐个调用观察者
* - 观察者就知晓了事情的发生,并能做出相应
* - 典型的如UI界面的各种event和listener
* - 或者AOP,实际上实现是代理,语义上也是一个观察者模式:当方法执行到这里,就触发AOP绑定的拦截器方法。(只是由代理给实现的)
*/
public class Main {
public static void main(String[] args) {
// 事件源,一个baby
Child child = new Child();
// 给他添加一些观察者(类似监听)
child.addObserver(new Dad());
child.addObserver(new Mum());
// 当发生业务场景,观察者会被触发
child.cry();
}

}

/**
* 事件类,可有可无。是为了给观察者传递当时的业务信息。
* @param <T>
*/
@AllArgsConstructor
class Event<T>{
T source;
String name;
String time;
}

/**
* 所有观察者的接口,观察者统一实现这个接口,发生事件的时候统一触发
* @param <R>
*/
interface Observer <R>{
public R actionOnEvent(Event<R>e);
}

/**
* 一个事件源
*/
class Child{
// 观察这个事件源的对象,注册到这里
List<Observer> observers = new ArrayList<>();

// 添加观察者
public void addObserver(Observer each){
this.observers.add(each);
}

public void cry(){
// 发生特定事件
System.out.println("Baby cry..........");
// 构造一个事件对象
Event<Child> e = new Event<>(this,"孩子哭了", new Date().toLocaleString());;
// 触发所有的观察者
for (Observer each : observers) {
each.actionOnEvent(e);
}
}
}

/**
* 一个观察者Dad
*/
class Dad implements Observer<Child>{

@Override
public Child actionOnEvent(Event<Child> e) {
System.out.println("Dad feed baby........");
return e.source;
}
}

/**
* 一个观察者Mum
*/
class Mum implements Observer<Child>{

@Override
public Child actionOnEvent(Event<Child> e) {
System.out.println("Mum pat baby........");
return e.source;
}
}