Pythonプログラミングでよく使われるデザインパターン(2)

ストラテジーパターン

ストラテジーパターンは、アルゴリズムを切り替えることができるようにするために使用されます。 ストラテジーは、異なるアルゴリズムを定義するインターフェースを提供し、アルゴリズムの実装を簡単に変更することができます。これにより、アルゴリズムの実装をカプセル化し、コードの再利用性を高めることができます。

以下は、Pythonでストラテジーパターンを実装する例です。

# ストラテジーの抽象クラス
class Strategy:
    def do_algorithm(self, data):
        pass

# 具体的なストラテジークラス1
class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data):
        return sorted(data)

# 具体的なストラテジークラス2
class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data):
        return reversed(sorted(data))

# コンテキストクラス
class Context:
    def __init__(self, strategy):
        self._strategy = strategy

    def set_strategy(self, strategy):
        self._strategy = strategy

    def do_some_business_logic(self, data):
        result = self._strategy.do_algorithm(data)
        return result

# メイン関数
if __name__ == '__main__':
    context = Context(ConcreteStrategyA())
    data = [4, 2, 1, 3, 5]
    result = context.do_some_business_logic(data)
    print(result)  # [1, 2, 3, 4, 5]

    context.set_strategy(ConcreteStrategyB())
    result = context.do_some_business_logic(data)
    print(result)  # [5, 4, 3, 2, 1]

例では、Strategyクラスがストラテジーの抽象クラスであり、ConcreteStrategyAとConcreteStrategyBは具体的なストラテジークラスです。Contextクラスはコンテキストクラスであり、ストラテジーを切り替えることができます。do_some_business_logicメソッドは、ストラテジーによって異なるアルゴリズムを実行するために使用されます。

最初にConcreteStrategyAを使用してアルゴリズムを実行し、次にConcreteStrategyBを使用してアルゴリズムを実行しています。ConcreteStrategyAはデータを昇順にソートし、ConcreteStrategyBはデータを降順にソートしています。

コマンドパターン

Commandパターンは、オブジェクト間の一連のアクションをカプセル化して、それらを扱いやすくします。これにより、呼び出し元は、オブジェクトの状態を知ることなく、オブジェクトの操作を実行することができます。Commandパターンは、コードの柔軟性、拡張性、保守性を高めるために使用されます。

Commandパターンには、4つの主要な要素があります。

Command(コマンド):アクションの実行方法を定義するインターフェースです。
ConcreteCommand(具体的なコマンド):Commandインターフェースを実装し、オブジェクトの実際のアクションをカプセル化します。
Invoker(呼び出し者):Commandオブジェクトを操作し、アクションをトリガーします。
Receiver(受信者):ConcreteCommandオブジェクトがアクションを実行するために必要なリソースを提供します。

以下は、PythonでCommandパターンを実装する例です。この例では、ファイルを作成、編集、削除するためのCommandオブジェクトがあります。Invokerオブジェクトは、ユーザーからのコマンドを取得し、適切なConcreteCommandオブジェクトを呼び出します。

# Commandインターフェース
class Command:
    def execute(self):
        pass

# ConcreteCommandオブジェクト
class CreateCommand(Command):
    def __init__(self, receiver, filename):
        self.receiver = receiver
        self.filename = filename

    def execute(self):
        self.receiver.create_file(self.filename)

class EditCommand(Command):
    def __init__(self, receiver, filename, content):
        self.receiver = receiver
        self.filename = filename
        self.content = content

    def execute(self):
        self.receiver.edit_file(self.filename, self.content)

class DeleteCommand(Command):
    def __init__(self, receiver, filename):
        self.receiver = receiver
        self.filename = filename

    def execute(self):
        self.receiver.delete_file(self.filename)

# Receiverオブジェクト
class Receiver:
    def create_file(self, filename):
        print(f"Created file '{filename}'")

    def edit_file(self, filename, content):
        print(f"Edited file '{filename}' with content '{content}'")

    def delete_file(self, filename):
        print(f"Deleted file '{filename}'")

# Invokerオブジェクト
class Invoker:
    def __init__(self):
        self.commands = []

    def add_command(self, command):
        self.commands.append(command)

    def execute_commands(self):
        for command in self.commands