美文网首页
观察者模式

观察者模式

作者: 井底蛙蛙呱呱呱 | 来源:发表于2019-04-13 14:20 被阅读0次
观察者模式在状态监测和事件处理等场景中是非常有用的。这种模式确保一个核心对象可以由一组未知并可能正在扩展的‘观察者’对象来监控。一旦核心对象的某个值发生变化各个观察者在核心对象发生变化时,有可能会处理不同的任务;核心对象不知道也不关心这些任务是什么,通常观察者也同样不知道、不关心其他的观察者正在做什么。下图是他在UML中的表现形式: 观察者模式
关于UML图中各个图标的意思

观察者实例

观察者模式在一个冗余备份系统中是非常有用的。我们可以编写一个核心对象来维持一些特定的值,然后用一个或多个观察者来创建该对象的一系列副本。例如,这些副本可能储存在数据库、远程主机或者一个本地文件夹中。让我们来实现这个核心对象的一些属性:

class Inventory(object):
    def __init__(self):
        self.observers = []
        self._product = None
        self._quantity = 0

    def attach(self, observer):
        self.observers.append(observer)
        
    @property
    def product(self):
        return self._product
    
    @product.setter
    def product(self, value):
        self._product = value
        self._update_observers()
        
    @property
    def quantity(self):
        return self._quantity
    
    @quantity.setter
    def quantity(self, value):
        self._quantity = value
        self._update_observers()
    
    def _update_observers(self):
        for observer in self.observers:
            observer()

这个对象有两个属性,对其执行赋值,便调用_update_observers方法。该方法所做的全部工作就是对所有可用的观察者进行遍历,好让他们知道发生了一些变化。在这里,我们直接调用观察者对象,而这个对象必须实现__call__函数来处理变化。这在许多面向对象的编程语言中是不可能的,但是在Python中,这是一种让我们的代码更具有可读性的捷径。

现在让我们实现一个简单的观察者对象,他只是将一些状态打印到控制台。

class ConsoleObserver(object):
    def __init__(self, inventory):
        self.inventory = inventory
    
    def __call__(self):
        print(self.inventory.product)
        print(self.inventory.quantity)

这里没什么特别激动的事情:在初始化函数中设置被观测的对象,以及当观察者被调用时,我们会做一些事。我们现在来对观察者进行简单的测试:

i = Inventory()
c = ConsoleObserver(i)
i.attach(c)
i.product = 'Widget'
i.quantity = 5

# 输出:
Widget
0
Widget
5

将观察者附加到库存对象后,每当我们改变这两个被观察者属性时,观察者就会调用并执行动作。我们甚至可以添加两个不同的观察者实例:

i = Inventory()
c1 = ConsoleObserver(i)
c2 = ConsoleObserver(i)
i.attach(c1)
i.attach(c2)
i.product = 'Widget'
i.quantity = 5

# 输出:
Widget
0
Widget
0
Widget
5
Widget
5

这一次我们改变产品时,会出现两组输出,每个观察者各一个。这里的关键理念是,我们可以很容易的添加两个完全不同类型的观察者,从而将数据同时备份至文件、数据库或者互联网应用中。

观察者模式将正在被观察者的代码和执行观察的代码分离。如果我们不使用模式,我们就必须要在每个属性中添加代码来处理可能出现的情况,例如登录到控制台,更新一个数据库或文件等。每个人物的代码都会被观察的对象混合在一起。想要维护他们将会是一个噩梦,在日后添加新的监控功能也会变得非常痛苦。

参考:
《Python3 面向对象编程》

相关文章

  • 11.9设计模式-观察者模式-详解

    设计模式-观察者模式 观察者模式详解 观察者模式在android中的实际运用 1.观察者模式详解 2.观察者模式在...

  • RxJava基础—观察者模式

    设计模式-观察者模式 观察者模式:观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式...

  • 前端面试考点之手写系列

    1、观察者模式 观察者模式(基于发布订阅模式) 有观察者,也有被观察者。 观察者需要放到被观察者列表中,被观察者的...

  • RxJava 原理篇

    一、框架思想 观察者模式观察者自下而上注入被观察者被观察者自上而下发射事件观察者模式 装饰器模式自上而下,被观察者...

  • 观察者模式

    观察者模式概念 观察者模式是对象的行为模式,又叫作发布-订阅(publish/subscrible)模式。 观察者...

  • 设计模式-观察者模式

    观察者模式介绍 观察者模式定义 观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为...

  • 观察者模式

    观察者模式 观察者模式的定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/s...

  • iOS设计模式之观察者模式

    观察者模式 1、什么是观察者模式 观察者模式有时又被称为发布(publish)-订阅(Subscribe)模式、模...

  • 观察者模式和发布订阅模式区别

    观察者模式 所谓观察者模式,其实就是为了实现松耦合(loosely coupled)。 在观察者模式中,观察者需要...

  • RxJava(二)

    一、观察者模式 1.1、传统的观察者模式 1.2、RxJava 的观察者模式 区别传统的观察者模式是一个 Obse...

网友评论

      本文标题:观察者模式

      本文链接:https://www.haomeiwen.com/subject/gyilwqtx.html