用户注册与通知系统中观察者模式解析

观察者模式

是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。

观察者设计模式可以解决哪些问题?

观察者模式解决了以下问题:

1对象之间的一对多依赖关系应该在不使对象紧密耦合的情况下定义。

2应该确保当一个对象改变状态时,会自动更新无限数量的依赖对象。

3一个对象可以通知无限数量的其他对象,这应该是可能的。

通过定义一个直接更新依赖对象状态的对象(主题)来定义对象之间的一对多依赖关系是不灵活的,因为它将主题提交(紧密耦合)到特定的依赖对象。紧密耦合的对象很难实现、更改、测试和重用,因为它们引用和了解(如何更新)许多具有不同接口的不同对象。

观察者设计模式描述了什么解决方案?

扫描二维码关注公众号,回复: 3691284 查看本文章

定义主题和观察者对象。

这样,当一个主题改变状态时,所有注册的观察者都会被自动通知和更新。

主题的唯一责任是维护一个观察者列表,并通过调用其update()操作来通知他们状态更改。

观察者的职责是在一个主题上注册(和注销)自己(获得状态变化的通知),并在被通知时更新他们的状态(使他们的状态与主题的状态同步)。

这使得主题和观察者松散耦合。主体和观察者对彼此没有明确的了解。可以在运行时独立地添加和删除观察者。

这种通知注册交互也称为发布-订阅。

请参阅下面的UML类和序列图。

耦合和典型的发布-订阅实现

通常情况下,观察者模式实现的“主题”(这是“观察”)的观察对象的状态变化,传达到观察者发生。 这种类型的实施被认为是“ 紧耦合的 ”,迫使观察员和主题意识到彼此,可以访问他们的内部零件,创造可能的问题 可伸缩性 、速度、信息恢复和维护(也称为事件或通知损失),有条件的缺乏灵活性分散所需的安全措施和可能的阻碍。 在某些( non-polling )的实现 发布-订阅模式 (也称为发布—订阅模式)中,这是通过创建一个专门的“消息队列”服务器来解决,有时一个额外的“消息处理程序”对象,随着添加阶段之间的观察者和观察到的对象的状态检查,因此“脱钩”的软件组件。 在这些情况下,消息队列服务器访问的观察家观察者模式,“订阅某些消息“知道只有预期的消息(不信,在某些情况下),但对消息发送者本身一无所知,接收方和发送方可能一无所知。 其他发布-订阅模式的实现,这些实现类似效果的通知和沟通感兴趣,完全不使用观察者模式。

在早期实现多窗口操作系统OS2和窗户,术语“发布-订阅模式”和“事件驱动软件开发”作为观察者模式的同义词。

实现

观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。

观察者模型分析:

https://github.com/surjitr/ObserverPattern

这是一个用于注册和通知观察者任何事件的观察者模式示例

#这是观察者可以注册的可观察类
class
Observable: #创建观察者类 def __init__(self): self.observers=[] #用于观察者注册 def register(self, observer): if not observer in self.observers: self.observers.append(observer) print("Observer %s registered" % observer) #用于观察者注销 def unregister(self, observer): if observer in self.observers: self.observer.remove(observer) print("Observer %s removed" % observer) #注销所有观察者 def unregister_all(self): del self.observers[:] print("Unregistered all observers") #观察者更新 def update_observers(self, * args, **kwargs): for observer in self.observers: observer.update(*args, **kwargs)
#检测观察者模式应用程序
from Observable import Observable
from observerbase import BaseClass

class ObserverA(BaseClass):
    #定义观察者A类

    def __init__(self):
        #观察者A的构造函数

    def update(self, *args, **kwargs):
        #当被调用时更新参数
        print("ObserverA update invoked")
        for arg in args:
            print(arg)
        for key,value in kwargs.items():
            print(key,":",value)

class ObserverB(BaseClass):
    #定义观察者B类

    def __init__(self):
        #观察者B的构造函数

    def update(self, *args, **kwargs):
        #当被调用时更新参数
        print("ObserverB update invoked")
        for arg in args:
            print(arg)
        for key,value in kwargs.items():
            print(key,":",value)


if __name__ == "__main__":
    underObservation = Observable()

    bot1 = ObserverA()
    bot2 = ObserverB()

    underObservation.register(bot1)
    underObservation.register(bot2)

    underObservation.update_observers(('SMA indicates SELL', 'Bollinger Resistance', 'SELL'), {"Lotsize": 37,
                                                                                               "TakeProfit": 300,
                                                                                               "SL": 50})
#观察者的抽象基类

from abc import ABCMeta, abstractmethod

class BaseClass(metaclass=ABCMeta):
    #用于创建观察者的基类

    def update(self, *args, **kwargs):
        pass # no need to define here. will handle in derived

#观察者模式的单元测试
import unittest
from Observable import Observable
from observerbase import BaseClass


class TestObserver(BaseClass):
    def __init__(self):
        args = []
        kwargs = {}

    def update(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        return


class UnitTestObserver(unittest.TestCase):
    #定义测试类

    def setUp(self):
        self.undOb = Observable()
        self.bot1 = TestObserver()
        self.bot2 = TestObserver()

    def tearDown(self):
        del self.undOb
        del self.bot1
        del self.bot2
    #观察者列表非空
    def test_defaultNoObserver(self):
        self.assertEqual(len(self.undOb.observers),0," Observer list is not empty")
    #重复观察者注册
    def test_DuplicateObservers(self):
        self.undOb.register(self.bot1)
        self.undOb.register(self.bot2)
        self.undOb.register(self.bot1)
        self.assertEqual(len(self.undOb.observers),2,"Duplicate observers registered")
    #移除所有观察者
    def test_RemoveAllSubscribers(self):
        self.undOb.register(self.bot1)
        self.undOb.register(self.bot2)
        self.undOb.register(self.bot1)
        self.undOb.unregister_all()
        self.assertEqual(len(self.undOb.observers), 0, "Observers still registered")


if __name__ == "__main__":
    unittest.main()

猜你喜欢

转载自www.cnblogs.com/xueadas/p/9837011.html