• 浅谈Python设计模式 -- 责任链模式


      声明:本系列文章主要参考《精通Python设计模式》一书,并且参考一些资料,结合自己的一些看法来总结而来。

      之前在最开始就聊了Python设计模式有三种,其中关于创建型和结构型设计模式基本都已经聊了,那么现在来聊聊关于Python设计模式的 行为型设计模式 。 

      行为型设计模式:

        用来处理系统实体之间通信的设计模式。

      接下来,聊一下关于行为型设计模式的第一种 --  责任链模式

     责任链模式

      根据《精通Python设计模式》书中介绍如下:

    责任链模式 -- 用于让多个对象处理一个请求时,或者用于预先不知道由哪个对象来处理某种特定请求时,其原则如下:

      1、存在一个对象链(链表、树或者其他便捷的数据结构)。

      2、一开始将请求发送给第一个对象,让其处理。

      3、对象决定是否处理该请求。

      4、对象将请求转发给下一个对象。

      5、重复该过程,直到达到链尾。

     可能看概念介绍还会很模糊,那么接下来看一下需求吧。

      需求

      假设有这么一个请假系统:员工若想要请3天以内(包括3天的假),只需要直属经理批准就可以了;如果想请3-7天,不仅需要直属经理批准,部门经理需要最终批准;如果请假大于7天,不光要前两个经理批准,也需要总经理最终批准。类似的系统相信大家都遇到过,那么该如何实现呢?首先想到的当然是if…else…,但一旦遇到需求变动,其臃肿的代码和复杂的耦合缺点都显现出来。简单分析下需求,“假条”在三个经理间是单向传递关系,像一条链条一样,因而,我们可以用一条“链”把他们进行有序连接。

      示例来源:阿里云:Python与设计模式 -- 责任链模式

      示例:

    class Manager():
        """经理类"""
        successor = None
        name = ''
        def __init__(self, name):
            self.name = name
        def setSuccessor(self, successor):
            # 设置上级
            self.successor = successor
        def handleRequest(self, request):
            # 处理请求
            pass
    
    class LineManager(Manager):
        '''直属经理'''
        def handleRequest(self, request):
            if request.requestType == 'DaysOff' and request.number <= 3:
                return '%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number)
            else:
                return '%s:%s Num:%d Accepted CONTINUE' % (self.name, request.requestContent, request.number)
                if self.successor != None:
                    self.successor.handleRequest(request)
    
    class DepartmentManager(Manager):
        '''部门经理'''
        def handleRequest(self, request):
            if request.requestType == 'DaysOff' and request.number <= 7:
                return '%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number)
            else:
                return '%s:%s Num:%d Accepted CONTINUE' % (self.name, request.requestContent, request.number)
                if self.successor != None:
                    self.successor.handleRequest(request)
    
    class GeneralManager(Manager):
        '''总经理'''
        def handleRequest(self, request):
            if request.requestType == 'DaysOff':
                return '%s:%s Num:%d Accepted OVER' % (self.name, request.requestContent, request.number)
    
    class Request():
        def __init__(self, requestType ,requestContent, number = 0):
            self.requestType = requestType
            self.requestContent = requestContent
            self.number = number
    
        def commit(self,generalManager):
            ret = generalManager.handleRequest(self)
            print(ret)
            return ret

     分析:

      1、有一个Request类,用来构建请求,同时调用commit方法提高到责任链的首段即 lineManager对象 来处理。

      2、lineManager在处理该请求时,去校验是否为 请假类型和请假天数,若为请求天数 > 3天,则判断是否有上级,若有则调用上级即 departManager对象来处理。

      3、部门领导如上,若请求天数 > 7天则提交给总经理 generalManager来处理,直到责任链的尾端。

      4、责任链处理到尾端,则返回处理结果,当然该示例中没有结果返回。

     使用:

    if  __name__=="__main__":
        line_manager = LineManager('LINE MANAGER')
        department_manager = DepartmentManager('DEPARTMENT MANAGER')
        general_manager = GeneralManager('GENERAL MANAGER')
    
        line_manager.setSuccessor(department_manager)
        department_manager.setSuccessor(general_manager)
    
        request = Request(requestContent="'Ask 1 day off'", requestType='DaysOff', number=1)
        request.commit(line_manager)
     
    
        request = Request(requestContent="'Ask 5 day off'", requestType='DaysOff', number=5)
        request.commit(line_manager)
    
        request = Request(requestContent="'Ask 10 day off'", requestType='DaysOff', number=10)
        request.commit(line_manager)

      上述代码案例:用编程专业术语来说是一个单向链表,若 经理也可以发布任务,给其下级,其下级处理了再发给下下级~~,以此类推,则 可以实现一个双向链表。

      这种链表组织:可以解耦发送方 和接收方。即 请求只需发送给 直属经理即可。而下方任务,只需发送给部门经理即可。

    该模式的优缺点:

     优点:
      1、将请求者与处理者分离,请求者并不知道请求是被哪个处理者所处理,易于扩展。

     缺点:

      1、如果责任链比较长,会有比较大的性能问题;
      2、如果责任链比较长,若业务出现问题,比较难定位是哪个处理者的问题。


     应用场景:
      2、若一个请求可能由一个对请求有链式优先级的处理群所处理时,可以考虑责任链模式。除本例外,银行的客户请求处理系统也可以用责任链模式实现(VIP客户和普通用户处理方式当然会有不同)。

      over~~~

  • 相关阅读:
    OpenStack trove原理及配置实践
    [转]在首席架构师手里,应用架构如此设计
    Servlet入门(一),超级详细!!!看完就会!!!!
    Redis入门
    Linux笔记02—Linux进阶应用
    Linux笔记01—linux基础入门
    Linux笔记00—计算机概论
    Linux上安装jdk
    SpringBoot入门
    排查问题的五个步骤
  • 原文地址:https://www.cnblogs.com/littlefivebolg/p/9932009.html
Copyright © 2020-2023  润新知