观察者模式

简介

观察者模式,首先设置一个观察者,针对某些事件或者对象进行观察。通过观察,观察者可能会做出一些反应,也可能不会。比如果保安观察监控,平常用户出入保安不会有反应,一旦发现小偷,保安就要立即做出相应的举动。


正文

观察者模式,也被称为订阅发布模式,主要有两种模式,拉模式和推模式,接下来我们演示一下:

拉模式:

class Subscribed:
    '''被订阅对象'''
    def __init__(self) -> None:
        self.observer_list = []
        self.__lastmessage = None

    def add_observer(self,observer):
        self.observer_list.append(observer)

    def del_observer(self,observer):
        self.observer_list.remove(observer)

    def add_newmessage(self,message):
        self.__lastmessage = message
    
    def get_newmessage(self):
        return self.__lastmessage
    
    def notify_all(self):
        for o in self.observer_list:
            o.get_newmessage(self)

class Observer:

    def __init__(self, name) -> None:
        self.name = name
        self.subscribed_list = []

    def subscribe(self,subscribed):
        self.subscribed_list.append(subscribed)
        subscribed.add_observer(self)


    def get_newmessage(self,subscribed):
        if subscribed in self.subscribed_list:
            print(self.name, "收到新消息:",subscribed.get_newmessage())



s = Subscribed()

o1 = Observer("观察者一号")
o1.subscribe(s)

o2 = Observer("观察者二号")
o2.subscribe(s)

s.add_newmessage("123456")
s.notify_all()

推模式:

class Subscribed:
    '''被订阅对象'''
    def __init__(self) -> None:
        self.observer_list = []
        self.__lastmessage = None

    def add_observer(self,observer):
        self.observer_list.append(observer)

    def del_observer(self,observer):
        self.observer_list.remove(observer)

    def add_newmessage(self,message):
        self.__lastmessage = message
    
    def get_newmessage(self):
        return self.__lastmessage
    
    def notify_all(self):
        for o in self.observer_list:
            o.get_newmessage(self,self.get_newmessage())    # 主要变化

class Observer:

    def __init__(self, name) -> None:
        self.name = name
        self.subscribed_list = []

    def subscribe(self,subscribed):
        self.subscribed_list.append(subscribed)
        subscribed.add_observer(self)


    def get_newmessage(self,subscribed,newmassage):
        if subscribed in self.subscribed_list:
            print(self.name, "收到新消息:",newmassage)



s = Subscribed()

o1 = Observer("观察者一号")
o1.subscribe(s)

o2 = Observer("观察者二号")
o2.subscribe(s)

s.add_newmessage("123456")
s.notify_all()

个人认为拉模式和推模式的主要区别是,

拉模式需要被订阅对象将自身传递给观察者,然后由观察者调用被订阅对象相应函数获取新数据

推模式则是将新数据直接传递给观察者。

拉模式的优点在于可以自己选择自己想要的数据,推模式的优点在于,如果已知需要的数据,则可以简单方便的将数据推给观察者。

观察者模式和生产者-消费者模式比较:

先说一下生产者-消费者模式,这个模式不属于23种设计模式中,但是也是我们开发常用的一种设计模式。

在个人理解中,生产者-消费者模式是在观察者模式中对观察者和观察对象进行解耦,在二者之间新增一个缓存区。

这使得被观察对象(生产者)不需要每次更新(生产)都去通知观察者(消费者),而是将更新的数据都存入缓存区,等待观察者(消费者)自己去获取。


总结

观察者模式的好处在于观察者可以自主决定是否需要订阅,从而达到松耦合的目的。但是随着观察者的数量慢慢上传,被订阅对象发送信息缓慢的问题也逐渐明显。从而导致生产者-消费者模式的出现。

上一篇:Java设计模式(观察者模式)


下一篇:配置相同VLAN之间能够相互通信