观察者模式-Python实现

观察者模式

定义

观察者模式(发布-订阅模式 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比赛看完了,那么就可以取消订阅前台小姐姐的通知,也不需要修改发布者和观察者的代码。

优点

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

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

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

缺点

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值