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

本文详细介绍了观察者模式,包括其定义、实战代码演示以及两种实现方式的比较。通过实际代码展示了如何使用Java内置API实现观察者模式,并探讨了该模式的优缺点和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.观察者模式的定义

定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

2.观察者模式实战

2.1观察者模式的结构和说明

这里写图片描述

Subject为目标,也叫被观察者,Observer为观察者。
Attach方法为添加观察者,detach方法为删除观察者,notify方法为通知观察者,执行notify时会调用观察者(Observer)的update方法更新。
ConcreteSubject为目标的具体实现类,ConcreteObserver为观察者的具体实现类。

2.2观察者模式的代码演示

统一的目标类:
这里写图片描述

具体的目标类:
这里写图片描述

统一的观察者接口:
这里写图片描述

具体的观察者:

这里写图片描述

测试类:

这里写图片描述

运行结果:

这里写图片描述

3.观察者模式详解

3.1实现的两种方式
推模型:目标对象主动向观察者推送目标的详细信息,推送的信息通常是目标对象的全部信息或者部分数据。例如:

这里写图片描述

拉模型:目标对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于观察者从目标对象中拉取数据。一般这种模型的实现中,会把目标对象的自身传给update参数。例如:

这里写图片描述

两种方式的比较:
1.推模型是假定目标对象知道观察者需要的数据,拉模型是目标对象不知道观察者需要什么数据,因此把自身传给观察者,由观察者来取值。
2.推模型会使观察者对象难以复用,拉模型下,update方法的参数是目标对象的本身,基本可以适应各种情况的需要。

3.2利用jdk内置的api实现观察者模式

java.util.Observable类是目标对象,即可观察者
java.util.Observer接口是观察者接口

Jdk实现的观察者模式与自己实现的对比
1.不需要再定义观察者和目标对象的接口了,jdk帮忙定义好了;
2.具体的目标实现里面不再需要维护观察者的注册信息了,这个在java中Observable类中已经帮忙实现好了;
3.触发通知的方式有改变,要先调用setChange()方法,这个是java为了帮助更精准的触发控制而提供的功能;
4.具体的观察者类里面,update方法同时支持推模型和拉模型。

具体的目标对象类,只需要继承Observable就行了,如下:
这里写图片描述
代码解释:
使用this.notifyObservers()是使用拉模型,就是将自身传给观察者;
使用this.notifyObservers(content)是使用推模型,就是将content传给观察者;

具体的观察者类,只需要实现observer接口就行了,如下:
这里写图片描述
代码解释:
Update方法的Observable是接受目标对象的引用,即拉模型的实现;Object arg是接受目标对象传过来的内容,是推模型的实现。

测试类:

这里写图片描述

执行结果如下:

这里写图片描述

3.3观察者的优点以及何时使用观察者模式

优点:
1.观察者模式实现了观察者与目标之间的抽象耦合
2.观察者模式实现了动态联动
3.观察者模式支持广播通信

观察者模式的本质:触发联动。建议在以下情况下选用观察者模式:
1.当一个抽象模型有两个方面,其中一个方面的操作依赖于另外一个方面的状态变化;
2.如果在更改一个对象的时候,需要同时连带改变其他对象,而且不知道究竟应该有多少对象需要被连带改变;
3.当一个对象必须通知其他对象,但是又希望这个对象与其他被它通知的对象是松散耦合的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值