<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          python 設(shè)計模式之責(zé)任鏈模式

          共 3429字,需瀏覽 7分鐘

           ·

          2022-04-28 23:27

          1. 責(zé)任鏈模式

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

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

          1. 鏈表

          2. 相同的接口

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

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

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

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

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

          1. 密碼長度大于6

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

          3. 包含特殊字符

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

          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 類是抽象處理者角色,它存在的意義是定義具體處理者角色必須實現(xiàn)的接口,這樣處理者角色在使用時才能規(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):
          """
          專門檢查長度
          """


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


          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個類是具體處理者角色,他們是CheckHanlderBase的子類,而CheckHanlderBase 是AbcCheckHandler的子類,我特地增加了CheckHanlderBase,為的是讓代碼更加簡潔,你可以去掉它,讓三個檢查類直接繼承AbcCheckHandler,但那樣很多代碼都會重復(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")

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

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

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

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

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

          缺點(diǎn):

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


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

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆精品三级电影 | 青娱乐亚洲精品视频在线观看 | 国产道高无码视频91 | 国产69久久精品成人看 | 天堂中文资源库 |