2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで設計するCommandパターン:アクションをオブジェクトとして抽象化する設計技法

Posted at

概要

Command(コマンド)パターンは、
「処理内容(アクション)」をオブジェクトとして抽象化することによって、
コマンドの実行・取り消し(Undo)・履歴管理・再実行(Redo)などを柔軟に設計するための構造パターンである。

実行対象と処理のタイミングを分離し、柔軟な操作制御・ロギング・マクロ処理が可能となる。


1. なぜCommandパターンが必要か?

❌ 直接関数呼び出しで操作を定義

button.on_click = save_file

→ 処理を変更・遅延・記録・Undoしたいときに対応しづらい


✅ 処理自体をオブジェクトに抽象化

button.set_command(SaveCommand(editor))
button.click()

アクションを操作対象から分離し、制御の自由度が高まる


2. 基本構造

✅ コマンドの抽象基底クラス

class Command:
    def execute(self):
        raise NotImplementedError

    def undo(self):
        raise NotImplementedError

✅ 具体的なコマンドクラス

class SaveCommand(Command):
    def __init__(self, editor):
        self.editor = editor
        self.prev_content = ""

    def execute(self):
        self.prev_content = self.editor.content
        print(f"Saving: {self.editor.content}")

    def undo(self):
        self.editor.content = self.prev_content
        print(f"Reverted to: {self.prev_content}")

✅ レシーバ(処理対象)

class TextEditor:
    def __init__(self):
        self.content = ""

✅ 実行者(Invoker)

class Button:
    def __init__(self, command):
        self.command = command

    def click(self):
        self.command.execute()

    def undo(self):
        self.command.undo()

✅ 使用例

editor = TextEditor()
editor.content = "Hello, world!"

save_cmd = SaveCommand(editor)
button = Button(save_cmd)

button.click()      # Saving: Hello, world!
editor.content = "New Content"
button.undo()       # Reverted to: Hello, world!

3. Python的応用:高階関数としてのCommand

class FunctionCommand(Command):
    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs

    def execute(self):
        return self.func(*self.args, **self.kwargs)
def greet(name):
    print(f"Hello, {name}!")

cmd = FunctionCommand(greet, "Toto")
cmd.execute()  # Hello, Toto!

4. 実務ユースケース

✅ Undo/Redo 実装

→ 文書編集、図形描画ツールなどの履歴操作


✅ マクロ機能・操作記録

→ 実行されたコマンドのログを残して一括実行・再実行


✅ GUIイベントのアクション分離

→ ボタンやメニューの操作をコマンドとして注入


✅ 非同期タスクや遅延実行(CommandQueue)

→ ジョブスケジューラ、バッチ処理の設計


5. よくある誤用と対策

❌ 単なる関数呼び出しで済ませてしまう

→ ✅ 状態管理・Undo・記録が必要なら明示的にCommandに抽象化


❌ コマンドが複雑化して1クラスに責務が集中

→ ✅ execute() / undo() の責務を明確に分離し、状態を保持するクラスとの連携を整理


❌ Invokerがコマンドに過度に依存

→ ✅ Commandインターフェース経由で操作し、疎結合を保つ


結語

Commandパターンとは、“処理をデータとして扱うことで、操作の自由度を最大化する”構造技法である。

  • アクションの実行、取り消し、再実行を構造化して制御
  • イベント駆動設計、マクロ、履歴管理などの基盤として機能
  • Pythonの第一級関数性を活かせば、実装も直感的でシンプル

Pythonicとは、“処理そのものをオブジェクト化し、設計の中で操る”ことであり、
Commandパターンはその動的な操作性と抽象化力を、アプリケーションに注入する技術である。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?