设计模式之观察者 (Observer) 模式

167 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

简介

观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。

正章

思考题 在我们的一个实现中,下列哪种说法正确?(多选) P42

public class WeatherDate {

// 实例变量声明
public void measurementsChanged() {
    float temp = getTemperature();
    float humidity = getHumidity();
    float pressure = getPressure();
    
    currentConditionsDisplay.update(temp, humidity, pressure);
    statisticsDisplay.update(temp, humidity, pressure);
    forecastDisplay.update(temp, humidity, pressure);
}

// 其他 WeatherData 方法

} [x] A. 我们是针对具体实现编程,而非针对接口

每个布告板都是直接进行更新 [x] B. 对于每个新的布告板,我们都得修改代码

每个新的布告板,都需加一行更新代码 [x] C. 我们无法在运行时动态地增加(或删除)布告板

没有针对接口编程,运行时无法更改布告板 [x] D. 布告板没有实现一个共同的接口

没有布告板的相关介绍,认为没有实现同一个接口

后来又学到 TypeScript 和 Golang 等语言,这些语言是存在鸭子类型,不需要显示继承类或者接口(但本书所有例子都是 Java ,所以不认为是鸭子类型)

【答案认为没有此选项】所有布告板都有相同的更新方式,看起来像实现了一个共同的接口

[x] E. 我们尚未封装改变的部分

布告板会动态更新,此处仍是针对实现编程 [x] F. 我们侵犯了 WeatherData 类的封装

修改了不属于我们负责的类

【答案认为没有此选项】方法没有入参,暗示必须在方法内修改

观察者模式 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新 P51

设计原则:为了交互对象之间的松耦合设计而努力 P53

松耦合把对象之间的互相依赖降到了最低,因此可以增加弹性,应对变化 所思所想 觉得观察者模式又像用到了策略,不同的观察者和不同的主题就类似于不同的策略;可能各个不同的设计模式都运用到 OO基础和OO原则,使得有点相似,但是解决的问题还是有所差异的

观察者模式也用得很多,以前用的各种事件监听器就是观察者模式,不过这种模式的观察者不需要主题的引用,注册由客户端实现。