Design Patterns(十六) Observer

Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically. Observer pattern falls under behavioral pattern category.

前言

    观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

观察者模式

基本介绍:
观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。

角色介绍:

1)抽象主题(Subject):
它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
2)具体主题(Concrete Subject):
将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3)抽象观察者(Observer):
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4)具体观察者(Concrete Observer):
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

观察者模式-UML图:


观察者模式-实例图:


代码:

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
89
90
91
92
93
94
import java.util.ArrayList;

/**
* @Auther: Arsenal
* @Date: 2020-03-20 22:46
* @Description: 观察者模式
*/
public class ObserverDemo {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver("观察者一号");
Observer observer2 = new ConcreteOberverOther("观察者二号");
subject.attach(observer);
subject.attach(observer2);
subject.notifyObserver();

}
}

/**
* 目标抽象类 Subject
*/
abstract class Subject {

protected ArrayList observers = new ArrayList<>();

//把观察者对象添加到观察者集合中
public void attach(Observer observer) {
observers.add(observer);
}

//把观察者对象剔除到观察者集合中
public void detach(Observer observer) {
observers.remove(observer);
}

//声明抽象方法
public abstract void notifyObserver();
}

/**
* 具体目标类 ConcreteSubject
*/
class ConcreteSubject extends Subject {

//实现通知的方法
@Override
public void notifyObserver() {
System.out.println("目标对象状态已变化......发送通知给观察者中");
for (Object object : observers) {
((Observer) object).update();
}
}
}

/**
* 观察者接口 Observer
*/
interface Observer {
public void update();
}

/**
* 具体的观察者
*/
class ConcreteObserver implements Observer {
private String observerName;

public ConcreteObserver(String observerName) {
this.observerName = observerName;
}

@Override
public void update() {
System.out.println(observerName + "我要更新一下我的状态了......");
}
}

/**
* 具体的观察者
*/
class ConcreteOberverOther implements Observer {

private String observerName;

public ConcreteOberverOther(String observerName) {
this.observerName = observerName;
}

@Override
public void update() {
System.out.println(observerName + "我要更新一下我的状态了......");
}
}

总结

观察者模式的注意事项和细节:

1.主要优点
(1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体的观察者角色。
(2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者对象只需要维持一个抽象观察者的集合,无需了解其具体观察者。
(3)观察者模式支持广播通信,观察目标会向所有已注册的观察者发送通知,降低了一对多系统的设计难度。
(4)观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有的系统代码。

2.主要缺点
(1)如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收到消息会耗费大量的时间。
(2)如果观察者和被观察者之间存在循环依赖,那么观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
(3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道目标观察对象发生了变化。

延伸

    观察者模式
    观察者模式-菜鸟教程
    设计模式之观察者模式
    Design Patterns - Observer Pattern
    尚硅谷Java设计模式,韩顺平图解java设计模式

Content
  1. 1. 前言
  2. 2. 观察者模式
  3. 3. 总结
  4. 4. 延伸