1. python 設(shè)計(jì)模式之責(zé)任鏈模式

        共 3429字,需瀏覽 7分鐘

         ·

        2022-04-28 23:27

        1. 責(zé)任鏈模式

        通俗點(diǎn)講,責(zé)任鏈?zhǔn)且粋€(gè)鏈表結(jié)構(gòu),這條鏈上有多個(gè)節(jié)點(diǎn),它們有相同的接口,各自有各自的責(zé)任和實(shí)現(xiàn)。當(dāng)有數(shù)據(jù)輸入時(shí),第一個(gè)節(jié)點(diǎn)看自己能否處理問題,如果可以就進(jìn)行處理,如果不能就數(shù)據(jù)交給下一個(gè)節(jié)點(diǎn)進(jìn)行處理,以此類推直到最后一個(gè)責(zé)任節(jié)點(diǎn)。

        上面這段描述里,我們可以總結(jié)出以下幾個(gè)關(guān)鍵信息

        1. 鏈表

        2. 相同的接口

        3. 節(jié)點(diǎn)有各自的任務(wù)

        4. 從第一個(gè)節(jié)點(diǎn)開始處理輸入,如果不能處理,交給下一個(gè)節(jié)點(diǎn)

        為了實(shí)現(xiàn)相同的接口,在責(zé)任鏈模式中需要一個(gè)抽象處理者角色來定義一個(gè)抽象接口,責(zé)任鏈上的節(jié)點(diǎn)是具體處理者角色,處理者必須實(shí)現(xiàn)由抽象處理者定義的抽象接口并各自實(shí)現(xiàn)具體功能。

        2. 責(zé)任鏈模式示例

        在網(wǎng)站上設(shè)置密碼時(shí),對(duì)密碼通常有如下要求:

        1. 密碼長(zhǎng)度大于6

        2. 包含小寫字母和大寫字母

        3. 包含特殊字符

        我就以檢查密碼是否合法為例子講解如何實(shí)現(xiàn)責(zé)任鏈模式,當(dāng)然,實(shí)踐中這樣的檢查是不需要使用責(zé)任鏈來實(shí)現(xiàn)的,只是這個(gè)例子更通俗易懂一些。

        2.1 抽象處理者角色

        from abc import ABC, abstractmethod


        class AbcCheckHandler(ABC):
        @abstractmethod
        def check_password(self, password):
        pass

        @abstractmethod
        def set_next(self, handler):
        pass

        AbcCheckHandler 類是抽象處理者角色,它存在的意義是定義具體處理者角色必須實(shí)現(xiàn)的接口,這樣處理者角色在使用時(shí)才能規(guī)范行為。

        2.2 具體處理者角色

        具體處理者角色是抽象處理者角色的子類

        class CheckHanlderBase(AbcCheckHandler):
        _next_handler = None
        def set_next(self, handler):
        self._next_handler = handler

        @abstractmethod
        def _check(self, password):
        pass

        def check_password(self, password):
        status, msg = self._check(password)
        if status:
        if self._next_handler:
        return self._next_handler.check_password(password)
        else:
        return True, ''
        else:
        return status, msg

        class LengthCheckHandler(CheckHanlderBase):
        """
        專門檢查長(zhǎng)度
        """


        def _check(self, password):
        if len(password) > 6:
        return True, ''
        return False, '長(zhǎng)度錯(cuò)誤'


        class CaseCheckHandler(CheckHanlderBase):
        """
        專門檢查大小寫
        """


        def _check(self, password):
        has_lower = False
        has_upper = False

        for letter in password:
        if 'a' < letter < 'z':
        has_lower = True
        if 'A' < letter < 'Z':
        has_upper = True

        if has_lower and has_upper:
        return True, ''
        else:
        return False, '大小寫不符合要求'


        class SpecialCheckHandler(CheckHanlderBase):
        def _check(self, password):
        for letter in ('!', '@', '#', '$'):
        if letter in password:
        return True, ''
        return False, '未包含特殊字符'


        def check_password(password):
        len_checker = LengthCheckHandler()
        case_checker = CaseCheckHandler()
        special_checker = SpecialCheckHandler()

        len_checker.set_next(case_checker)
        case_checker.set_next(special_checker)

        status, msg = len_checker.check_password(password)
        if status:
        print(f"{password} 檢查通過")
        else:
        print(f"{password} 檢查不通過: {msg}")

        LengthCheckHandler, CaseCheckHandler, SpecialCheckHandler這3個(gè)類是具體處理者角色,他們是CheckHanlderBase的子類,而CheckHanlderBase 是AbcCheckHandler的子類,我特地增加了CheckHanlderBase,為的是讓代碼更加簡(jiǎn)潔,你可以去掉它,讓三個(gè)檢查類直接繼承AbcCheckHandler,但那樣很多代碼都會(huì)重復(fù)。

        2.3 調(diào)用責(zé)任鏈

        def get_password_checker():
        len_checker = LengthCheckHandler()
        case_checker = CaseCheckHandler()
        special_checker = SpecialCheckHandler()

        len_checker.set_next(case_checker)
        case_checker.set_next(special_checker)
        return len_checker

        def check_password(password):
        password_checker = get_password_checker()
        status, msg = password_checker.check_password(password)
        if status:
        print(f"{password} 檢查通過")
        else:
        print(f"{password} 檢查不通過: {msg}")


        if __name__ == "__main__":
        check_password("1324sfED!")
        check_password("323!")
        check_password("323df3!")
        check_password("323DKS3!")
        check_password("skdjOWRJ")

        對(duì)于責(zé)任鏈的調(diào)用者,你不必關(guān)心鏈上有多少個(gè)節(jié)點(diǎn),節(jié)點(diǎn)的順序是什么,這些都是在創(chuàng)建責(zé)任鏈時(shí)決定的,由創(chuàng)建者負(fù)責(zé),你只需要將數(shù)據(jù)輸入給責(zé)任鏈即可。

        3. 責(zé)任鏈模式的優(yōu)缺點(diǎn)

        優(yōu)點(diǎn):

        1. 增加或者刪除責(zé)任很方便

        2. 降低耦合度,對(duì)于請(qǐng)求的發(fā)送者,無需關(guān)心接收者都有哪些,順序如何

        缺點(diǎn):

        1. 可能會(huì)在程序調(diào)試方面制造一些麻煩,但可以通過合理的日志輸出來規(guī)避


        瀏覽 133
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 新婚女裸体按摩伦理 | 18禁黄网站网址免费入口 | 国产99久久久国产精品~~牛 | 天天插天天射 | 国产精品久久久久久久久大全 |