淺談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~~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM