当前位置: 首页 > article >正文

设计模式之监听模式

  本文将会介绍设计模式中的监听模式
  监听模式是一种一对多的关系,可以有任意个(一个或多个)观察者对象同时监听某一个对象。监听的对象叫观察者(Observer),被监听的对象叫作被观察者(Observable)。被观察者对象在状态或内容(数据)发生变化时,会通知所有观察者对象,使它们能够做出相应的变化。
  监听模式又名观察者模式,顾名思义就是观察与被观察的关系。比如你在烧开水的时候看着它开没开,你就是观察者,水就是被观察者;再比如你在带小孩,你关注他是不是饿了,是不是渴了,是不是撒尿了,你就是观察者,小孩就是被观察者。观察者模式是对象的行为模式,又叫发布/订阅(Publish/Subscribe)模式、模型/视图(Model/View)模式、源/监听器(Source/Listener)模式或从属者(Dependents)模式。
  监听模式的核心思想就是在被观察者与观察者之间建立一种自动触发的关系。

例子

  以家中常见的热水器为例,需对水温进行监控,当水温在50-70℃时,会发出警告:可以用来洗澡了!当水温在100℃时,会发出警告:可以用来饮水了!在这里洗澡模式和饮用模式扮演了监听的角色,而热水器则是被监听的对象。一旦热水器中的水温度发生变化,监听者就能及时知道并做出相应的判断和动作。
  UML类图如下:
监听模式的类图
Python代码如下:

# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod


# 观察者的基类
class Observer(metaclass=ABCMeta):
    @abstractmethod
    def update(self, observable, object):
        pass


# 被观察者的基类
class Observable:
    def __init__(self):
        self.__observers = []

    def addObserver(self, observer):
        self.__observers.append(observer)

    def removeObserver(self, observer):
        self.__observers.remove(observer)

    def notifyObservers(self, object=0):
        for o in self.__observers:
            o.update(self, object)


# 热水器
class WaterHeater(Observable):
    def __init__(self):
        super().__init__()
        self.__temperature = 25

    def getTemperature(self):
        return self.__temperature

    def setTemperature(self, temperature):
        self.__temperature = temperature
        print(f"当前温度是:{str(self.__temperature)}℃")
        self.notifyObservers()


# 洗澡模式
class WashingMode(Observer):
    def update(self, observable, object):
        if isinstance(observable, WaterHeater) and 50 <= observable.getTemperature() <= 70:
            print("水已烧好!温度正好,可以用来洗澡了。")


# 饮用模式
class DrinkingMode(Observer):
    def update(self, observable, object):
        if isinstance(observable, WaterHeater) and observable.getTemperature() >= 100:
            print("水以烧开!可以用来饮用了。")


def testWaterHeater():
    heater = WaterHeater()
    washingObser = WashingMode()
    drinkingObser = DrinkingMode()
    heater.addObserver(washingObser)
    heater.addObserver(drinkingObser)
    heater.setTemperature(40)
    heater.setTemperature(60)
    heater.setTemperature(100)


if __name__ == '__main__':
    testWaterHeater()

输出结果如下:

当前温度是:40℃
当前温度是:60℃
水已烧好!温度正好,可以用来洗澡了。
当前温度是:100℃
水以烧开!可以用来饮用了。

总结

  在设计监听模式的程序时需要注意以下几点:

  • 要明确谁是观察者谁是被观察者,只要明白谁是应该关注的对象,问题也就明白了。一般观察者与被观察者之间是多对一的关系,一个被观察对象可以有多个监听对象(观察者)。
  • Observable在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否订阅Subject的通知。
  • 被观察者至少需要有三个方法:添加监听者、移除监听者、通知Observer的方法。观察者至少要有一个方法:更新方法,即更新当前的内容,做出相应的处理。
  • 添加监听者和移除监听者在不同的模型称谓中可能会有不同命名。

http://www.kler.cn/a/8105.html

相关文章:

  • 查看php已安装扩展命令
  • 【C++】设计模式
  • css 编写注意-1-命名约定
  • Odoo 免费开源 ERP:通过 JavaScript 创建对话框窗口的技术实践分享
  • QT-基础-1-Qt 中的字符串处理与常见数据类型
  • 【Leetcode】1705. 吃苹果的最大数目
  • 第二章 SpringBoot整合ES7
  • 签订合同Signing a Contract
  • TenserRT(一)模型部署简介
  • 人人都能看懂的Spring源码解析,Spring如何解决循环依赖
  • Leetcode653. 两数之和 IV - 输入二叉搜索树
  • JavaScript 解析Json字符串的性能比较分析代码
  • WeakTr阅读笔记
  • Spring销毁的几种实现
  • 【vSphere | Python】vSphere Automation SDK for Python Ⅵ—— VM Guest Processes APIs
  • 实时决策系统中 OpenMLDB 的常见架构整合方式
  • 【微信小程序-原生开发】系列教程目录(已完结)
  • 只依赖Tensorrt和opencv的yolov5源代码
  • GPT的未来--基于标准接口的由计算机和无数工业软件构成的联合体
  • 青少年CTF训练平台-WEB-部分wp
  • vue给input框属性赋值的方法
  • Android系统重要组件AMS
  • 【Spring】4—声明式事务
  • 【Mysql系列】——详细剖析数据库中的存储引擎
  • Java面向对象三剑客之——继承
  • Burp Suite的使用(常用模块)