一、模式定义
1.观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
2.观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式
3.观察者模式是一种对象行为型模式
二、模式结构
观察者模式包含如下角色。
1. Subject(目标)
目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,它可以存储任意数量的观察者对象,它提供一个接口来增加和删除观察者对象,同时它定义了的通知方法notify()。目标类可以是接口,也可以是抽象类或实现类。
2.ConcreteSubject(具体目标)
具体目标是目标类的子类,通常它包含经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。
3. Observer(观察者)
观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。
4. ConcreteObserver(具体观察者)
在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update( )方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的观察者集合中或通过detach()方法将自己从目标类的观察者集合中删除。
三、例子
# @Time : 2022/11/21 14:25
# @Author : ZQH
# @FileName: Observer.py
# @Software: PyCharm
from abc import ABCMeta, abstractmethod
# 抽象观察者
class Zqh0224StaffObserve(metaclass=ABCMeta):
@abstractmethod
def update(self,notice): # notice 是一个 notice类对象
pass
2.ConcreteObserver
# @Time : 2022/11/21 14:25
# @Author : ZQH
# @FileName: ConcreteObserver.py
# @Software: PyCharm
from Observer import Zqh0224StaffObserve
class Zqh0224HuaweiFans(Zqh0224StaffObserve):
def __init__(self,name):
self.name = name
self.information = None
def update(self,notice):
self.information = self.name + '收到消息:' + notice.information
3.Subject
# @Time : 2022/11/21 14:24
# @Author : ZQH
# @FileName: Subject.py
# @Software: PyCharm
# 目标 天猫华为手机旗舰店
class Zqh0224HuaweiMall():
def __init__(self):
self.observes = [] # 订阅的观察者列表
# 添加观察者
def attach(self, obs):
self.observes.append(obs)
# 删除观察者
def detach(self, obs):
self.observes.remove(obs)
# 发布消息,每个观察者能接受消息
def notify(self):
for obs in self.observes:
obs.update(self)
4.ConcreteSubject
# @Time : 2022/11/21 14:25
# @Author : ZQH
# @FileName: ConcreteSubject.py
# @Software: PyCharm
from Subject import Zqh0224HuaweiMall
# 具体目标 到货通知
class Zqh0224ArrivalNotification(Zqh0224HuaweiMall):
def __init__(self, company_info=None):
super().__init__()
self.__company_info = company_info
# 读操作
@property
def information(self):
return self.__company_info
# 写操作
@information.setter
def information(self, info):
self.__company_info = info
self.notify()
四、优缺点
1.观察者模式的优点
(1)观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递长期,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
(2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,每一个具体观察者都符合抽象观察者的定义。观察目标不需要了解其具体观察者,只需知道它们都有一个共同的接口即可。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(3)观察者模式支持广播通信,观察目标会向所有注册的观察者发出通知,简化了一对多系统设计的难度。
(4)观察者模式符合“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
2.观察者模式的缺点
(1)如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用可能导致系统崩溃。
(3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。