设计模型|观察者模式

Yeren Lv3

定义

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式是一种对象行为型模式。

动机

建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

设计类图

结构

  • Subject: 目标
  • ConcreteSubject: 具体目标
  • Observer: 观察者
  • ConcreteObserver: 具体观察者

样例代码

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
package DesignPattern;

import java.util.ArrayList;

abstract class Subject{
protected ArrayList<Observer> ObjList = new ArrayList<>();
public void attach(Observer observer){
ObjList.add(observer);
}
public void detach(Observer observer) {
ObjList.remove(observer);
}
public abstract void _notify();
}

interface Observer{
void update();
}

class ConcreteSubject extends Subject{
@Override
public void _notify() {
for(Observer obs:ObjList){
obs.update();
}
}
}

class ConcreteObserver implements Observer{
private Subject subject;

@Override
public void update() {
System.out.println("this observer has been updated");
}

public ConcreteObserver(Subject sub){
subject = sub;
}
}

public class Observe {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer observe1 = new ConcreteObserver(subject);
Observer observe2 = new ConcreteObserver(subject);
subject.attach(observe1);
subject.attach(observe2);
subject._notify();
}
}

总结分析

  • 观察者模式描述了如何建立对象与对象之间的依赖关系,如何构造满足这种需求的系统。
  • 这一模式中的关键对象是观察目标和观察者,一个目标可以有任意数目的与之相依赖的观察者,一旦目标的状态发生改变,所有的观察者都将得到通知。
  • 作为对这个通知的响应,每个观察者都将即时更新自己的状态,以与目标状态同步,这种交互也称为发布-订阅(publishsubscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通知。

优点

  • 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
  • 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
  • 观察者模式支持广播通信。
  • 观察者模式符合“开闭原则”的要求。

缺点

  • 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

例题(书中例题)

Sunny软件公司欲开发⼀款多人联机对战游戏(类似魔兽世界、星际争霸等游戏),在该游戏中,多个玩家可以加⼊同⼀战队组成联盟,当战队中某⼀成员受到敌人攻击时将给所有其他 盟友发送通知,盟友收到通知后将作出响应。
Sunny软件公司开发人员通过对系统功能需求进行分析,发现在该系统中战队成员之间的联动过程可以简单描述如下: 联盟成员受到攻击–>发送通知给盟友–>盟友作出响应。
如果按照上述思路来设计系统,由于联盟成员在受到攻击时需要通知他的每⼀个盟友,因此 每个联盟成员都需要持有其他所有盟友的信息,这将导致系统开销较大,因此Sunny公司开发人员决定引入⼀个新的角色——“战队控制中心”——来负责维护和管理每个战队所有成员的信 息。当⼀个联盟成员受到攻击时,将向相应的战队控制中心发送求助信息,战队控制中心再 逐⼀通知每个盟友,盟友再作出响应。

答案参考书本

  • Title: 设计模型|观察者模式
  • Author: Yeren
  • Created at : 2023-08-22 00:00:00
  • Updated at : 2023-08-22 00:00:00
  • Link: https://blog.yeren.xyz/2023/08/22/DP-observer-pattern/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments