观察者模式

您所在的位置:网站首页 python观察者 观察者模式

观察者模式

2023-11-30 03:57| 来源: 网络整理| 查看: 265

观察者模式 定义

观察者模式(发布-订阅模式 Publish Subscribe Pattern):定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者,使它们能够自动更新自己。

简单就是说你有一个观察者列表,这个列表中的函数或者某种功能都在观察某个事件的发生,一旦发生,这些函数或者功能就会自动执行。

场景

例如,员工趁老板不在,都在玩自己的东西,同时观察着前台小姐姐,前台小姐姐在老板回来的时候,发布通知让各同事回到工作状态。

实现 没有设计模式的实现

先看看没有使用观察者模式的实现代码

# 看股票的同学 class StockObserver: def update(self): print('看股票的同学 关闭股票行情,继续工作') # 看NBA的同学 class NbaObserver: def update(self): print('看NBA的同学 关闭NBA,继续工作') # 前台小姐姐 class Receptionist: def notify(self): print("老板回来了,各单位请注意...") StockObserver().update() NbaObserver().update() if __name__ == "__main__": receptionist = Receptionist() receptionist.notify()

这样写,看似没有任何问题,但如果再出现几个调皮的同事,一个玩游戏的,一个打瞌睡的,一个。。。他们都需要知道老板回来。

程序就会变成下面这样

# 前台小姐姐 class Receptionist: def notify(self): print("老板回来了,各单位请注意...") StockObserver().update() NbaObserver().update() PlayGameObserver().update() SleepyObserver().update() ...

每次都要修改原来的代码,而且代码只会越来越庞大和复杂。

如果,在老板回来之前,看NBA的同学的NBA比赛看完了,不需要前台小姐姐通知了,又要改代码。

观察者模式实现

用观察者模式来实现上面的例子

# 抽象观察者类 class Observer(object): def __init__(self, name, publish): self.name = name self.publish = publish def update(self): pass # 具体观察者类-看股票的同学 class StockObserver(Observer): def update(self): print(self.publish.subject_status, self.name, '关闭股票行情,继续工作') # 具体观察者类-看NBA的同学 class NbaObserver(Observer): def update(self): print(self.publish.subject_status, self.name, '关闭NBA,继续工作') # 抽象发布者类 class Publish(object): def attach(self, observer): pass def detach(self, observer): pass def notify(self): pass # 具体发布者类-前台小姐姐 class Receptionist(Publish): def __init__(self): self.observer_list = [] self.subject_status = "" def attach(self, observer): self.observer_list.append(observer) def detach(self, observer): self.observer_list.remove(observer) def notify(self): self.subject_status = "老板回来了" print("老板回来了,各单位请注意...") for item in self.observer_list: item.update() if __name__ == "__main__": publisher = Receptionist() stock = StockObserver('看股票的同学', publisher) nba = NbaObserver('看NBA的同学', publisher) publisher.attach(stock) publisher.attach(nba) publisher.notify()

为什么要用观察者模式?

采用观察者模式,如果再来一个打游戏的同学,他也需要知道老板回来,那么直接订阅前台小姐姐的通知即可,不需要修改发布者和观察者的代码;

如果,在老板回来之前,看NBA的同学的NBA比赛看完了,那么就可以取消订阅前台小姐姐的通知,也不需要修改发布者和观察者的代码。

优点

使彼此交互的对象保持松耦合。

当需要添加其他对象时,无需对发布者和观察者做任何修改。

可以随时添加和删除观察者。

缺点

实现不当可能会增加复杂性,导致性能降低。

通知有时是不可靠的,并导致竞争条件或不一致性。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3