Python 如何实现职责链设计模式?什么是职责链设计模式?Python 职责链设计模式示例代码

什么是职责链(Chain of Responsibility)设计模式?

职责链(Chain of Responsibility)设计模式是一种行为型设计模式,旨在构建一个对象链,每个对象都有机会处理请求,并且可以将请求传递给链中的下一个对象。

在这里插入图片描述

在这个模式中,请求沿着链条依次传递,直到其中的某个对象处理请求为止。每个处理器(Handler)对象都包含一个指向下一个处理器的引用,形成了一个链式结构。请求进入链条的顶端,并从顶端的处理器开始处理,若顶端处理器无法处理该请求,它会将请求传递给下一个处理器,直至找到合适的处理器为止。
在这里插入图片描述
这种模式的主要目的是解耦发送者和接收者,使多个对象都有机会处理请求,而不需要明确指定请求的接收者。这样可以增强系统的灵活性,因为发送者不需要知道请求最终会由哪个对象处理,同时也可以动态地调整和扩展处理器链。

主要角色:
  1. 抽象处理者(Handler): 定义了处理请求的接口,通常包含一个指向下一个处理者的引用(后继者)。该角色提供一个处理请求的方法,通常是一个抽象方法或者是一个虚拟方法,子类需要实现该方法。抽象处理者可以决定是否将请求传递给下一个处理者。

  2. 具体处理者(ConcreteHandler): 实现了抽象处理者定义的接口,在收到请求时负责处理请求。如果能够处理请求,则直接进行处理;如果不能处理,则将请求传递给下一个处理者。

优点:
  1. 解耦发送者和接收者: 发送者无需知道请求的具体处理者,降低了发送者和接收者之间的耦合度,增强了系统的灵活性。

  2. 动态的请求处理流程: 可以动态地改变和调整处理请求的顺序和流程,增加了灵活性和可扩展性。

  3. 单一职责原则: 每个具体处理者只负责处理自己能够处理的请求,遵循了单一职责原则。

  4. 可拓展性: 可以灵活地新增、删除或调整处理者,以适应不同的业务需求。

  5. 简化了对象之间的连接: 无需发送者了解整个处理链的结构,只需要将请求发送给链条的起始处理者即可。

缺点:
  1. 请求未必被处理: 如果没有合适的处理者处理请求,可能会导致请求未被处理。

  2. 链过长可能影响性能: 如果处理链过长,可能会影响性能,因为请求需要在整个链条上进行传递和寻找处理者。


Python 职责链设计模式示例代码(一):

假设我们要实现在线支付系统中,需要根据用户的信用评级给予不同的授信额度。这个场景可以使用职责链模式来实现。

from abc import ABC, abstractmethod# 抽象处理者
class CreditHandler(ABC):def __init__(self, successor=None):self.successor = successordef set_successor(self, successor):self.successor = successor@abstractmethoddef check_credit(self, user):pass# 具体处理者1 - 优秀信用用户
class ExcellentCreditHandler(CreditHandler):def check_credit(self, user):if user['credit_score'] >= 80:print(f"Excellent credit score for {user['name']}. Credit limit: 50000")elif self.successor:self.successor.check_credit(user)# 具体处理者2 - 良好信用用户
class GoodCreditHandler(CreditHandler):def check_credit(self, user):if 60 <= user['credit_score'] < 80:print(f"Good credit score for {user['name']}. Credit limit: 20000")elif self.successor:self.successor.check_credit(user)# 具体处理者3 - 一般信用用户
class FairCreditHandler(CreditHandler):def check_credit(self, user):if user['credit_score'] < 60:print(f"Fair credit score for {user['name']}. Credit limit: 10000")elif self.successor:self.successor.check_credit(user)# 客户端代码
if __name__ == "__main__":# 用户信息user1 = {'name': '张三', 'credit_score': 85}user2 = {'name': '李四', 'credit_score': 70}user3 = {'name': '王五', 'credit_score': 50}# 创建处理者链excellent_handler = ExcellentCreditHandler()good_handler = GoodCreditHandler()fair_handler = FairCreditHandler()# 设置处理者顺序excellent_handler.set_successor(good_handler)good_handler.set_successor(fair_handler)# 发送请求excellent_handler.check_credit(user1)excellent_handler.check_credit(user2)excellent_handler.check_credit(user3)

这个示例模拟了一个根据用户信用评级给予不同授信额度的场景。根据用户的信用评级,不同的处理者会决定用户的授信额度,如果用户信用评级不符合任何处理者的条件,则不给予授信。


Python 职责链设计模式示例代码(二):

假设我们有一个在线购物系统,需要根据用户的会员等级给予不同的优惠。这个场景可以用职责链模式来实现。

from abc import ABC, abstractmethod# 抽象处理者
class DiscountHandler(ABC):def __init__(self, successor=None):self.successor = successordef set_successor(self, successor):self.successor = successor@abstractmethoddef apply_discount(self, user, amount):pass# 具体处理者1 - VIP会员折扣
class VIPDiscountHandler(DiscountHandler):def apply_discount(self, user, amount):if user['is_vip']:print(f"VIP discount applied for {user['name']}. Final amount: {amount * 0.7}")elif self.successor:self.successor.apply_discount(user, amount)# 具体处理者2 - 普通会员折扣
class RegularDiscountHandler(DiscountHandler):def apply_discount(self, user, amount):if user['is_regular']:print(f"Regular member discount applied for {user['name']}. Final amount: {amount * 0.9}")elif self.successor:self.successor.apply_discount(user, amount)# 具体处理者3 - 无折扣
class NoDiscountHandler(DiscountHandler):def apply_discount(self, user, amount):print(f"No discount applied for {user['name']}. Final amount: {amount}")# 客户端代码
if __name__ == "__main__":# 用户信息user1 = {'name': 'Alice', 'is_vip': True, 'is_regular': False}user2 = {'name': 'Bob', 'is_vip': False, 'is_regular': True}user3 = {'name': 'Eve', 'is_vip': False, 'is_regular': False}# 创建处理者链vip_handler = VIPDiscountHandler()regular_handler = RegularDiscountHandler()no_discount_handler = NoDiscountHandler()# 设置处理者顺序vip_handler.set_successor(regular_handler)regular_handler.set_successor(no_discount_handler)# 发送请求vip_handler.apply_discount(user1, 100)vip_handler.apply_discount(user2, 100)vip_handler.apply_discount(user3, 100)

这个示例模拟了一个用户购买商品时根据其会员等级获得不同折扣的场景。根据用户是否是 VIP 会员或普通会员,处理者会决定是否给予折扣,如果不符合条件,则没有折扣。


使用职责链设计模式时,需要注意哪些地方?

在使用职责链设计模式时,需要注意以下几个方面:

  1. 链的构建: 确保正确构建处理者链。每个处理者都应该知道其后继者是谁,以便请求可以沿着链传递。

  2. 避免循环链: 确保链不会形成循环,否则可能导致请求陷入无限循环,影响系统性能。

  3. 请求的处理: 每个处理者应该明确自己能够处理的请求类型和条件,确保不同处理者之间的处理逻辑不重叠或冲突。

  4. 适当的终止条件: 确保有适当的终止条件。如果没有一个处理者能够处理请求,需要有默认处理或者终止请求的处理方式。

  5. 灵活性与可扩展性: 职责链模式的灵活性是其优势之一,但也要确保链条的灵活性不会影响到代码的维护和扩展。

  6. 性能考虑: 过长的处理者链可能会影响性能,因为每个请求需要在整个链条上进行传递和寻找处理者。在设计时需权衡灵活性与性能。

  7. 单一职责原则: 每个处理者最好只负责一种类型的请求,遵循单一职责原则。

  8. 清晰的责任划分: 处理者的责任应该清晰,每个处理者的作用和职责应该被明确定义,以避免混乱和不必要的复杂性。

综上所述,使用职责链模式时需注意合理构建链条、避免循环、定义清晰的终止条件和责任划分,以确保系统的正确性、可维护性和扩展性。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

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

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

相关文章

动手学深度学习——循环神经网络的从零开始实现(原理解释+代码详解)

文章目录 循环神经网络的从零开始实现1. 独热编码2. 初始化模型参数3. 循环神经网络模型4. 预测5. 梯度裁剪6. 训练 循环神经网络的从零开始实现 从头开始基于循环神经网络实现字符级语言模型。 # 读取数据集 %matplotlib inline import math import torchfrom torch import …

五、hdfs常见权限问题

1、常见问题 2、案例 &#xff08;1&#xff09;问题 &#xff08;2&#xff09;hdfs的超级管理员 &#xff08;3&#xff09;原因 没有使用Hadoop用户对hdfs文件系统进行操作。 在Hadoop文件系统中&#xff0c;Hadoop用户相当于Linux系统中的root用户&#xff0c;是最高级别用…

react实现步进器

创建一个步进器组件&#xff0c;包含当前步骤&#xff08;currentStep&#xff09;的状态以及前进和后退的操作&#xff1a; import React, { useState } from react;function Stepper() {const [currentStep, setCurrentStep] useState(1);const handleNext () > {setCu…

⑩② 【MySQL索引】详解MySQL`索引`:结构、分类、性能分析、设计及使用规则。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL索引 ⑩② 【MySQL索引】1. 索引2. 索引的…

搞科研、写论文,如何正确使用GPT?AIGC技术解析、提示词工程高级技巧、AI绘图、ChatGPT/GPT4应用

目录 专题一 OpenAI开发者大会最新技术发展及最新功能应用 专题二 AIGC技术解析 专题三 提示词工程高级技巧 专题四 ChatGPT/GPT4的实用案例 专题五 让ChatGPT/GPT4成为你的论文助手 专题六 让ChatGPT/GPT4成为你的编程助手 专题七 让ChatGPT/GPT4进行数据处理 专题八 …

Wordpress页面生成器:Elementor 插件制作网站页面教程(图文完整)

本文来教大家怎么使用Wordpress Elementor页面编辑器插件来自由创建我们的网页内容。很多同学在面对建站的时候,一开始都是热血沸腾信心满满的,等到实际上手的时候就会发现有很多问题都是无法解决的,希望本篇Elementor插件使用指南能够帮助到你。 Wordpress Elementor页面编…

使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)

图像锐化1 获取源工程可访问huiningLi的gitee可在此工程的基础上进行学习。 实验要求 5.1实验目的、要求 实验目的&#xff1a; &#xff08;1&#xff09;掌握图像增强的原理与相关方法。 &#xff08;2&#xff09;能使用VC实现图像增强的一些相关功能。 实验要求&#xf…

【python】均值、中值和高斯滤波详解和示例

本文对均值、中值和高斯滤波进行详解&#xff0c;以帮助大家理解和使用。 这里写目录标题 均值滤波中值滤波高斯滤波核大小为&#xff08;9,9&#xff09;核大小为&#xff08;51,51&#xff09; 小结 下面是示例中使用的原图。 均值滤波 均值滤波是一种简单的平滑滤波器&…

PyTorch微调权威指南3:使用数据增强

如果你曾经参与过 PyTorch 模型的微调&#xff0c;可能会遇到 PyTorch 的内置变换函数&#xff0c;这使得数据增强变得轻而易举。 即使你之前没有使用过这些功能&#xff0c;也不必担心。 在本文中&#xff0c;我们将深入研究 PyTorch 变换换函数的世界。 我们将探索你可以使用…

CTFhub-RCE-过滤目录分隔符 /

根据源代码信息可知&#xff0c;过滤掉了/ <?php $res FALSE; if (isset($_GET[ip]) && $_GET[ip]) { $ip $_GET[ip]; $m []; if (!preg_match_all("/\//", $ip, $m)) { $cmd "ping -c 4 {$ip}"; exec($cmd,…

【开源】基于Vue.js的高校实验室管理系统的设计和实现

项目编号&#xff1a; S 015 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S015&#xff0c;文末获取源码。} 项目编号&#xff1a;S015&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…

数据结构与集合源码

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

【数据结构与算法】线性表 - 顺序表

目录 1. 线性表2.顺序表3.顺序表的优缺点4.实现&#xff08;C语言&#xff09;4.1 头文件 seqList.h4.2 实现 seqList.c 1. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见…

音视频转换软件Permute mac中文板特点介绍

Permute mac是一款Mac平台上的媒体格式转换软件&#xff0c;由Chaotic Software开发。它可以帮助用户快速地将各种音频、视频和图像文件转换成所需格式&#xff0c;并提供了一些常用工具以便于用户进行编辑和处理。 Permute mac软件特点 - 支持大量格式&#xff1a;支持几乎所…

汇编-指针

一个变量如果包含的是另一个变量的地址&#xff0c; 则该变量就称为指针(pointer) 。指针是操作数组和数据结构的极好工具&#xff0c;因为它包含的地址在运行时是可以修改的。 .data arrayB byte 10h, 20h, 30h, 40h ptrB dword arrayB ptrB1 dword OFFSET arrayBarray…

Linux:权限篇 (彻底理清权限逻辑!)

shell命令以及运行原理&#xff1a; Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09;“ &#xff0c;但我们一般用户&#xff0c;不能直接使用kernel。而是通过kernel的“外壳”程序&#xff0c;也就是所谓的shell&#xff0c;来…

YOLOV5部署Android Studio安卓平台NCNN

坑非常多&#xff0c;兄弟们&#xff0c;我已经踩了三天的坑了&#xff0c;我这里部署了官方的yolov5s和我自己训练的yolov5n的模型 下载Android Studio&#xff0c;配置安卓开发环境&#xff0c;这个过程比较漫长。 安装cmake&#xff0c;注意安装的是cmake3.10版本。 根据手机…

LeetCode——字符串(Java)

字符串 简介[简单] 344. 反转字符串[简单] 541. 反转字符串 II[中等] 151. 反转字符串中的单词 简介 记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路&#xff0c;如果有错误&#xff0c;可以在评论区提醒一下。 [简单] 344. 反转字符串…

【IPC】消息队列

1、IPC对象 除了最原始的进程间通信方式信号、无名管道和有名管道外&#xff0c;还有三种进程间通信方式&#xff0c;这 三种方式称之为IPC对象 IPC对象分类&#xff1a;消息队列、共享内存、信号量(信号灯集) IPC对象也是在内核空间开辟区域&#xff0c;每一种IPC对象创建好…

15分钟,不,用模板做数据可视化只需5分钟

测试显示&#xff0c;一个对奥威BI软件不太熟悉的人来开发数据可视化报表&#xff0c;要15分钟&#xff0c;而当这个人去套用数据可视化模板做报表&#xff0c;只需5分钟&#xff01; 数据可视化模板是奥威BI上的一个特色功能板块。用户下载后更新数据源&#xff0c;立即就能获…