Python: шаблон проектирования цепочки ответственности с несколькими аргументами

У меня есть следующий код с парой вложенных условий if-else, которые я хотел бы реорганизовать. Чтобы не усложнять пример, я не определяю вспомогательные функции (например, disable_check, check_last_alarm, get_kpi_value, …)

if disable_check(config, date):
    threshold = get_threshold()
    last_date = get_last_date()
    
    if check_last_alarm(config, date, update_freq):
        kpi_value = get_kpi_value(config, last_date)
        
        if trigger_kpi_alarm(kpi_value):
            return kpi_value
            
    if extraordinary_alarm(config, date, threshold):
        kpi_value = get_kpi_value(config, last_date)
        
        if trigger_kpi_alarm(kpi_value):
            return kpi_value

Моя идея заключалась в том, чтобы применить шаблон проектирования цепочки ответственности, например (черновик)

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Optional

from performance_tracker_dashboard.src.helper_functions import 

class Handler(ABC):

    @abstractmethod
    def set_next(self, handler: Handler) -> Handler:
        pass

    @abstractmethod
    def handle(self, request) -> Optional[str]:
        pass


class AbstractCheck(Handler):
    _next_handler: Handler = None

    def set_next(self, handler: Handler) -> Handler:
        self._next_handler = handler
        return handler

    @abstractmethod
    def handle(self, request: Any) -> str:
        if self._next_handler:
            return self._next_handler.handle(request)

        return None

class DisableCheck(AbstractCheck):
     def handle(self, request: Any) -> str:
     # TODO - how to integrate logic?
         if request == "last_alarm":
             return f"Last Alarm was not sufficient"
         else:
             return super().handle(request)
  
class LastAlarmCheck(AbstractCheck):
    def handle(self) -> str:
        pass
        
class KPIAlarmCheck(AbstractCheck):
    def handle(self) -> str:
        pass
        
class ExtraordinaryCheck(AbstractCheck):
    def handle(self) -> str:
        pass
        

def client_code(handler: Handler) -> None:
    # TODO- how to define the request arg?
    result = handler.handle(request)
    
if __name__ == "__main__":
    disable_check = DisableCheck()
    last_alarm = LastAlarmCheck()
    kpi_alarm = KPIAlarmCheck()
    extraordinary_alarm = ExtraordinaryCheck()

    disable_check.set_next(last_alarm).set_next(kpi_alarm).set_next(extraordinary_alarm).set_next(kpi_alarm)
    client_code(disable_check)

Вопросов:

  1. Возможен ли этот шаблон проектирования для данной ситуации? Если нет, у вас есть альтернативная идея?
  2. Как реализовать методы конкретных проверочных классов? Некоторые из них могут принимать входные данные из предыдущего конкретного класса проверки, и я не уверен, как это реализовать.

Черновик основан на этой веб-странице: https://refactoring.guru/design-patterns/chain-of-responsibility/python/example

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *