请关注【来玩AI】公众号体验人工智能
来玩AI >>>
Python 实现观察者模式
观察者模式
模式是一种常用的设计模式,可以在对象之间建立一对多的依赖关系。Python中实现观察者模式有多种方式,下面给出一种基于类和装饰器的实现方式:
python代码实现
class Observer:
def update(self, observable, *args, **kwargs):
pass
class Observable:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def remove_observer(self, observer):
self._observers.remove(observer)
def notify_observers(self, *args, **kwargs):
for observer in self._observers:
observer.update(self, *args, **kwargs)
class Person(Observable):
def __init__(self, name):
super().__init__()
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
self.notify_observers(value)
class Police(Observer):
def update(self, observable, *args, **kwargs):
print('Police: {} is now named {}'.format(observable, args[0]))
class Friend(Observer):
def update(self, observable, *args, **kwargs):
print('Friend: {} is now named {}'.format(observable, args[0]))
person = Person('Tom')
police = Police()
friend = Friend()
person.add_observer(police)
person.add_observer(friend)
person.name = 'Jerry'
说明
这段代码定义了三个类:Observer、Observable和Person。Observer是观察者接口,定义了update方法;Observable是被观察者接口,定义了add_observer、remove_observer和notify_observers方法;Person是一个具体的被观察者类。在Person中,我们使用@property和@name.setter装饰器来定义属性name,并在setter方法中调用notify_observers方法通知所有观察者。
下面定义了两个具体的观察者类:Police和Friend。这些观察者类实现了Observer接口,重写了update方法,在update方法中打印出被观察者的名字以及更新后的名字。最后我们创建了一个Person对象,并向它添加了两个观察者(Police和Friend)。我们通过修改Person的name属性来触发notify_observers方法,从而通知所有观察者。
应用场景
观察者模式适用于以下场景:
-
当一个对象的状态发生改变时,需要通知其他对象并自动更新。
-
当两个或多个对象之间存在一种依赖关系,其中一个对象的某些变化将影响到其他对象。
-
当一个对象需要将自己的状态更新通知给多个其他对象,而这些对象的类型和数量都不确定时,可以使用观察者模式来实现松耦合的通信。
-
当一个对象需要与其他对象共享一些信息,而且这些信息可能在运行时动态改变时,可以使用观察者模式来维护共享信息的一致性。
例如,在GUI编程中,用户界面上的控件可能会互相影响,例如修改一个文本框的内容可能会导致另一个标签的文字也随之改变。此时就可以使用观察者模式,将控件之间的依赖关系建立起来,并在控件状态发生改变时自动更新其他控件。另外,比如在游戏开发中,角色和怪物之间可能存在一种攻击关系,当角色攻击怪物时,怪物的血量需要减少,同时角色的经验值也需要增加。这时就可以使用观察者模式,将角色和怪物建立起攻击关系,并在攻击时通知对方进行相应处理。
请关注【来玩AI】公众号体验人工智能
来玩AI >>>
https://www.zhiyidata.cn/chatgpt/play