Commandパターン
Commandパターン
code:python
from dataclasses import dataclass
from typing import Callable
# content に対して処理を行うコールバック関数がある
def say(content, shout=False):
if shout:
print(f"shouting {content!r}!!!!")
return
print(f"{content!r}.")
def write(content):
print(f"writing {content!r}.")
# 引数の受け渡しに使うオブジェクト
@dataclass
class FuncConfig:
func: Callable
kwargs: dict
class Executor:
def __init__(self):
self.functions = []
def execute(self):
for fn in self.functions:
fn.func("Hello", **fn.kwargs)
def append_hook(self, *funcs):
for fn in funcs:
self.functions.append(fn)
exctr = Executor()
# わざわざ、FuncConfigを自分で生成するのは大変
exctr.append_hook(*hooks)
exctr.execute()
このようなコマンドは以下のように改善可能
code:python
from abc import ABC, abstractmethod
from typing import Any
class Command(ABC):
@abstractmethod
def execute(self, content: str) -> None:
pass
class SayCommand(Command):
def __init__(self, shout: bool = False):
self.shout = shout
def execute(self, content: str) -> None:
if self.shout:
print(f"shouting {content!r}!!!!")
else:
print(f"{content!r}.")
class WriteCommand(Command):
def execute(self, content: str) -> None:
print(f"writing {content!r}.")
class CompositeCommand(Command):
def __init__(self):
self._commands = []
def add_command(self, command: Command) -> None:
self._commands.append(command)
def execute(self, content: str) -> None:
for command in self._commands:
command.execute(content)
executor = CompositeCommand()
executor.add_command(SayCommand(shout=True))
executor.add_command(WriteCommand())
executor.execute("Hello")