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

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

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

在这里插入图片描述

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

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

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

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

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

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

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

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

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

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


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

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

python">from abc import ABC, abstractmethod

# 抽象处理者
class CreditHandler(ABC):
    def __init__(self, successor=None):
        self.successor = successor

    def set_successor(self, successor):
        self.successor = successor

    @abstractmethod
    def 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 职责链设计模式示例代码(二):

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

python">from abc import ABC, abstractmethod

# 抽象处理者
class DiscountHandler(ABC):
    def __init__(self, successor=None):
        self.successor = successor

    def set_successor(self, successor):
        self.successor = successor

    @abstractmethod
    def 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.niftyadmin.cn/n/5194365.html

相关文章

C++多线程编程(2):四种线程管理方法

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 线程管理get_idsleep_forsleep_untilyield 线程管理 有一个this_thread的名称空间中定义了许多的线程管理方法&#xff1a; get_id&#xff1a;获取当前线程idsleep_for&#xff1a;当前线程休眠一段时间sleep_…

自定义业务异常处理类加入全局处理器中

自定义业务异常处理类并将其加入全局异常处理器&#xff0c;从而避免业务层直接处理异常造成代码污染&#xff0c;达到业务清晰简洁。 描述 在进行分类模块开发时&#xff0c;删除某个分类时当分类关联了菜品和套餐时&#xff0c;是不允许删除的。我们在管理端删除的时候会提示…

收发电子邮件

电子邮件是Internet提供的又一个重要服务项目。早在1987年9月20日&#xff0c;中国首封电子邮件就是从北京经意大利向前联邦德国卡尔斯鲁厄大学发出的&#xff0c;在中国首次实现了与Internet的连接&#xff0c;使中国成为国际互联网大家庭中的一员。现在随着Internet的迅速发展…

ADS村田电感.mod(spice netlist文件)和.s2p模型导入与区别

ADS村田电感.mod&#xff08;spice netlist文件&#xff09;和.s2p模型导入与区别 简介环境过程s2pspice netlist&#xff08;.mod文件&#xff09;导入和结果对比 简介 记录了ADS村田电感.mod&#xff08;spice netlist文件&#xff09;和.s2p模型导入与区别 环境 ADS2020 …

遥感数据

在研究中&#xff0c;我们常需要遥感数据。在下面的网站中&#xff0c;可以得到遥感数据。 EarthExplorer (usgs.gov)https://earthexplorer.usgs.gov/登陆网站&#xff1a; 通常&#xff0c;在Additional Criteria中&#xff0c;可以下载遥感数据。 不过&#xff0c;这个选项…

pandas教程:Periods and Period Arithmetic 周期和周期运算

文章目录 11.5 Periods and Period Arithmetic&#xff08;周期和周期运算&#xff09;1 Period Frequency Conversion&#xff08;周期频度转换&#xff09;2 Quarterly Period Frequencies&#xff08;季度周期频度&#xff09;3 Converting Timestamps to Periods (and Back…

Scalable Exact Inference in Multi-Output Gaussian Processes

Orthogonal Instantaneous Linear Mixing Model TY are m-dimensional summaries&#xff0c;ILMM means ‘Instantaneous Linear Mixing Model’&#xff0c;OILMM means ‘Orthogonal Instantaneous Linear Mixing Model’ 辅助信息 作者未提供代码

牛客网刷题笔记三 寻找第K大+两数之和+合并两个排序的链表+用两个栈实现队列

算法题牛客网NC88 寻找第K大 题目&#xff1a; 思路就是做个排序&#xff0c;要求时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)&#xff0c;因此选用快排。代码&#xff1a; class Solution:def quickSort(self, a, start, end):if start > end:returnval a[start]…