Цепочка обязанностей

Описание
Цепочка обязанностей — поведенческий шаблон проектирования предназначенный для организации в системе уровней ответственности.

Цепочка обязанностей помогает строить цепочки объектов. Запрос входит с одного конца и проходит через каждый объект, пока не найдет подходящий обработчик.


Пример
Опишем пример создания классов цепочка обязанностей на примере изменения значений класса Device.

Базовый класс, который создает цепочку модификаций CreatureModifier. Параметр next_modifier ссылкой на модификатор, который необходимо вызвать следующим. Метод set_froz применяет цепочку обязанностей к объекту, если параметр next_modifier есть. Метод add_modifier формирует цепочку обязанностей.

Создадим класс цепочку DoubleModifier, унаследовав его от родителя CreatureModifier. Изменим метод, который применяется к цепочке и вызовем родительский метод цепочки (обязательно).

Класс NoModidier обрывает цепочку, так как у него нет вызова родительского метода set_froz.

from dataclasses import dataclass
from typing import ClassVar


@dataclass
class Device:
    name: str
    value1: int
    value2: int

    def __str__(self):
        return f'{self.name} ({self.value1}/{self.value2})'


@dataclass
class CreatureModifier:
    device: Device
    next_modifier: ClassVar = None

    def add_modifier(self, modifier):
        if self.next_modifier:
            self.next_modifier.add_modifier(modifier)
        else:
            self.next_modifier = modifier

    def set_froze(self):
        if self.next_modifier:
            self.next_modifier.set_froze()


@dataclass
class NoModidier(CreatureModifier):

    def set_froze(self):
        print('Отменить изменения')


@dataclass
class DoubleModifier(CreatureModifier):

    def set_froze(self):
        print(f'Удвоение значения {self.device.name}')
        self.device.value1 *= 2
        self.device.value2 /= 2
        super().set_froze()


if __name__ == '__main__':
    stove = Device('Печь', 100, 100)
    print(stove)

    root = CreatureModifier(stove)

    #root.add_modifier(NoModidier(stove))

    root.add_modifier(DoubleModifier(stove))
    root.add_modifier(DoubleModifier(stove))

    root.set_froze()  # применить цепочку
    print(stove)

Вывод
Цепочка обязанностей может быть реализована как центральная конструкция или цепочкой ссылок. Вы можете включать объекты в цепочку и контролировать порядок модификаторов. Каждый элемент может остановить цепочку модификаций.