设计模式--第八章 职责链模式

第一章 前言
第二章 观察者模式
第三章 状态模式
第四章 中介模式
第五章 装饰器模式
第六章 单例模式
第七章 克隆模式
第八章 职责链模式
第九章 代理模式
第十章 外观模式
第十一章 迭代模式
第十二章 组合模式
第十三章 构建模式
第十四章 适配模式
第十五章 策略模式
第十六章 简单工厂模式
第十七章 工厂方法模式
第十八章 抽象工厂模式
第十九章 命令模式
第二十章 备忘录模式
第二十一章 享元模式
第二十二章 访问模式
第二十三章 模板模式
第二十四章 桥接模式
第二十五章 解释器模式
第二十六章 过滤器模式
第二十七章 对象池技术
第二十八章 回调机制
第二十九章 MVC模式
附录



1. 核心思想

为避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。将这些接收对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责模式也称为责任链模式,它将请求的发送者和接收者解耦了。客户端不需要知道请求处理者的明确信息和处理的具体逻辑,甚至不需要知道链的结构,它只需要将请求进行发送即可。

比如请教条的审批,我们并不需要知道假条处理的具体细节,甚至不需要知道假条去哪儿了,只需要知道假条有人会处理。而假条的处理流程是一手接一手的责任传递,处理假条的所有人构成了一条责任的链条,如下图所示。

处理请假条流程

链条上的每一个人只处理自己职责范围内的请求,对于自己处理不了的请求,直接交给下一个责任人。这就是程序设计中职责模式的核心思想。在职责模式中我们可以随时随地增加或者更改责任人,甚至可以更改责任人的顺序,增加了系统的灵活性。但是有时候可能会导致一个请求无论如何也得不到处理,它会被放置在链条末端。

2. UML类图

职责模式UML类图

3. 框架代码

from abc import ABC, abstractmethod


class Request:
    """请求(内容)的封装类"""
    pass

class Requester:
    """请求发送者"""

    def __init__(self, nextHandler = None) -> None:
        self._nextHandler: Responsible = nextHandler

    def sendRequest(self, request:Request):
        if self._nextHandler is not None:
            self._nextHandler.handleRequest(request)

class Responsible(ABC):
    """请求处理者基类"""

    def __init__(self, nextHandler = None) -> None:
        self._nextHandler: Responsible = nextHandler

    def setNextHandler(self, nextHandler):
        self._nextHandler = nextHandler

    @abstractmethod
    def handleRequest(self, request: Request) -> None:
        pass

class NoteForLeave(Request):
    def __init__(self, name, day_off, reason) -> None:
        self._name = name
        self._day_off = day_off
        self._reason = reason

    def getName(self):
        return self._name

    def getDayOff(self):
        return self._day_off

    def getReason(self):
        return self._reason


class Leaver(Requester):
    """请假人"""

    def __init__(self, name, nextHandler: Responsible = None) -> None:
        super().__init__(nextHandler)
        self._name = name

    def setNextHandler(self, nextHandler: Responsible):
        self._nextHandler = nextHandler

    def sendRequest(self, request: NoteForLeave):
        print(
            f"{self._name} 申请请假 {request.getDayOff()} 天。请假事由:{request.getReason()}")
        return super().sendRequest(request)


class Supervisor(Responsible):
    """主管"""

    def __init__(self, name, title="Supervisor", nextHandler=None) -> None:
        super().__init__(nextHandler)
        self._name = name
        self._title = title

    def setnextHandler(self, nextHandler: Responsible):
        self._nextHandler = nextHandler

    def handleRequest(self, request: NoteForLeave):
        if request.getDayOff() <= 2:
            print(
                f"同意 {request.getName()} 请假 {request.getDayOff()} 天。签字人:{self._name}({self._title})")
        if self._nextHandler is not None:
            self._nextHandler.handleRequest(request)


class DepartmentManager(Responsible):
    """部门总监"""

    def __init__(self, name, title="DepartmentManager", nextHandler=None) -> None:
        super().__init__(nextHandler)
        self._name = name
        self._title = title

    def setnextHandler(self, nextHandler: Responsible):
        self._nextHandler = nextHandler

    def handleRequest(self, request: NoteForLeave):
        if 2 < request.getDayOff() <= 5:
            print(
                f"同意 {request.getName()} 请假 {request.getDayOff()} 天。签字人:{self._name}({self._title})")
        if self._nextHandler is not None:
            self._nextHandler.handleRequest(request)


class CEO(Responsible):
    """CEO"""

    def __init__(self, name, title="CEO", nextHandler=None) -> None:
        super().__init__(nextHandler)
        self._name = name
        self._title = title

    def setnextHandler(self, nextHandler: Responsible):
        self._nextHandler = nextHandler

    def handleRequest(self, request: NoteForLeave):
        if 5 < request.getDayOff() <= 22:
            print(
                f"同意 {request.getName()} 请假 {request.getDayOff()} 天。签字人:{self._name}({self._title})")
        if self._nextHandler is not None:
            self._nextHandler.handleRequest(request)

class Administrator(Responsible):
    """行政人员"""

    def __init__(self, name, title="Administrator", nextHandler=None) -> None:
        super().__init__(nextHandler)
        self._name = name
        self._title = title

    def setnextHandler(self, nextHandler: Responsible):
        self._nextHandler = nextHandler

    def handleRequest(self, request: NoteForLeave):
        print(
            f"{request.getName()} 的请假申请已审核,情况属实!已备案处理。处理人:{self._name}({self._title})")
        if self._nextHandler is not None:
            self._nextHandler.handleRequest(request)


if __name__ == "__main__":
    director_leader = Supervisor(name="Eren", title="客户端研发部经理")
    department_manager = DepartmentManager(name="Eric", title="技术研发中心总监")
    ceo = CEO(name="Helen", title="创新文化公司CEO")
    administrator = Administrator(name="Nina", title="行政中心总监")

    director_leader.setnextHandler(nextHandler=department_manager)
    department_manager.setnextHandler(nextHandler=ceo)
    ceo.setnextHandler(nextHandler=administrator)

    print("\n")
    sunny = Leaver(name="Sunny", nextHandler=director_leader)
    sunny.sendRequest(NoteForLeave(name=sunny._name,
                     day_off=1, reason="参加MDCC大会"))

    print("\n")
    tony = Leaver(name="Tony", nextHandler=director_leader)
    tony.sendRequest(NoteForLeave(name=sunny._name,
                                 day_off=5, reason="家里有急事"))

    print("\n")
    pony = Leaver(name="Pony", nextHandler=director_leader)
    pony.sendRequest(NoteForLeave(name=sunny._name,
                                 day_off=15, reason="出国深造"))

4. 模型说明

4.1 设计要点

在设计职责模式的程序时要注意以下几点:

  1. 请求者与请求内容:确认谁要发送请求,发送请求的对象称为请求者。请求的内容通过发送请求时的参数进行传递。
  2. 有哪些责任人:责任人是构成责任链的关键要素。请求的流动方向是链条中的线,而责任人则是链条上的节点,线和节点共同构成了一条链条。
  3. 对责任人进行抽象:真实世界中的责任人多种多样,纷繁复杂,有不同的职责和功能;但他们也有一个共同的特征——都可以处理请求。所以需要对责任人进行抽象,使他们具有责任的可传递性。
  4. 责任人可自由组合:责任链上的责任人可以根据业务的具体逻辑进行自由的组合和排序。

4.2 优缺点

  1. 优点:
    • 降低耦合度。它将请求的发送者和接收者解耦。
    • 简化了对象。它使得对象不需要知道链的结构。
    • 增强给对象指派职责的灵活性,可改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任人。
    • 增加新的处理类很方便。
  2. 缺点:
    • 不能保证请求一定被接收。
    • 系统性能将受到一定的影响,而且在进行代码调试时不太方便,可能会造成循环调用。

5. 应用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求在运行时刻自动确定。
  2. 请求的处理具有明显的一层层传递关系。
  3. 请求的处理流程和顺序需要程序运行时动态确定。
  4. 常见的审批流程(账务报销、转岗申请等)。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值