设计模式Python版 职责链模式


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、职责链模式

职责链模式(Chain of Responsibility Pattern)

  • 定义:避免将请求发送者与接收者耦合在一起,让多个对象都有机会接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

  • 解决问题:如何让多个对象都有机会来处理同一个请求?

  • 使用场景:

    • 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定。客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
    • 具体场景:工作流系统中实现公文的分级审批,Web应用开发中创建一个过滤器(Filter)链来对请求数据进行过滤
  • 组成:

    • Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类。因为每个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。
    • ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求。在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者。在具体处理者中可以访问链中下一个对象,以便请求的转发。
  • 补充说明:

    • 职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。
    • 链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并让请求沿着链传递,由链上的处理者对请求进行相应的处理。
    • 客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,实现请求发送者和请求处理者解耦。
    • 职责链模式结构的核心在于引入了一个抽象处理者。
    • 在职责链模式里,很多对象由每个对象对其下家的引用而连接起来形成一条链。
    • 职责链模式并不创建职责链。职责链的创建工作必须由系统的其他部分来完成,一般是在使用该职责链的客户端中创建职责链。
  • 优点:

    • 职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
    • 由于链的创建过程由客户端负责,因此增加新的具体处理者类对原有类库无任何影响,无须修改已有类的源代码,符合开闭原则。
    • 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
  • 缺点:

    • 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理。
    • 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。

在这里插入图片描述

二、职责链模式示例

使用职责链模式来实现采购单的分级审批

  • 抽象类Approver充当抽象处理者,Director、VicePresident、President和Congress充当具体处理者,PurchaseRequest充当请求类。
  • 说明:Congress类没有转发请求
### 职责链模式

"""请求类"""


class PurchaseRequest:
    def __init__(self, amount: float, number: int, purpose: str):
        self.amount = amount  # 采购金额
        self.number = number  # 采购单编号
        self.purpose = purpose  # 采购目的


"""抽象处理者"""


class Approver:
    def __init__(self, name):
        self.name = name  # 审批者姓名
        self.successor: Approver = None  # 后继对象

    def process_request(self, request: PurchaseRequest):
        # 抽象处理请求方法
        raise NotImplementedError


"""具体处理者"""


class Director(Approver):
    # 主任
    def __init__(self, name):
        super().__init__(name)

    def process_request(self, request):
        if request.amount < 50000:
            # 模拟处理请求
            print(
                f"主任 {self.name} 审批采购单:{request.number},金额:{request.amount}元,采购目的:{request.purpose}"
            )
        else:
            # 转发请求
            self.successor.process_request(request)


class VicePresident(Approver):
    # 副董事长
    def __init__(self, name):
        super().__init__(name)

    def process_request(self, request):
        if request.amount < 100000:
            # 模拟处理请求
            print(
                f"副董事长 {self.name} 审批采购单:{request.number},金额:{request.amount}元,采购目的:{request.purpose}"
            )
        else:
            self.successor.process_request(request)


class President(Approver):
    # 董事长
    def __init__(self, name):
        super().__init__(name)

    def process_request(self, request):
        if request.amount < 500000:
            # 模拟处理请求
            print(
                f"董事长 {self.name} 审批采购单:{request.number},金额:{request.amount}元,采购目的:{request.purpose}"
            )
        else:
            self.successor.process_request(request)


class Congress(Approver):
    # 董事会
    def __init__(self, name):
        super().__init__(name)

    def process_request(self, request):
        # 模拟处理请求
        print(
            f"召开董事会审批采购单:{request.number},金额:{request.amount}元,采购目的:{request.purpose}"
        )

客户端代码

zs = Director("张三")
ls = VicePresident("李四")
ww = President("王五")
meeting = Congress("董事会")

# 创建职责链
zs.successor = ls
ls.successor = ww
ww.successor = meeting

# 创建采购单
pr1 = PurchaseRequest(45000.5, 10001, "购买《三国演义》。")
zs.process_request(pr1)
pr1 = PurchaseRequest(60000.5, 10002, "购买《水浒传》。")
zs.process_request(pr1)
pr1 = PurchaseRequest(160000.5, 10003, "购买《西游记》。")
zs.process_request(pr1)
pr1 = PurchaseRequest(800000.5, 10004, "购买《红楼梦》。")
zs.process_request(pr1)

输出结果

主任 张三 审批采购单:10001,金额:45000.5元,采购目的:购买《三国演义》。
副董事长 李四 审批采购单:10002,金额:60000.5元,采购目的:购买《水浒传》。
董事长 王五 审批采购单:10003,金额:160000.5元,采购目的:购买《西游记》。 
召开董事会审批采购单:10004,金额:800000.5元,采购目的:购买《红楼梦》。  

三、职责链模式分类

职责链模式可分为纯的职责链模式和不纯的职责链模式两种

  • 纯的职责链模式
    • 一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个:要么承担全部责任,要么将责任推给下家。
    • 而且在纯的职责链模式中,要求一个请求必须被某一个处理者对象所接收,不能出现某个请求未被任何一个处理者对象处理的情况。
  • 不纯的职责链模式
    • 在一个不纯的职责链模式中,允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求。
    • 而且一个请求可以最终不被任何处理者对象所接收。

您正在阅读的是《设计模式Python版》专栏!关注不迷路~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值