概要
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パターンはその動的な操作性と抽象化力を、アプリケーションに注入する技術である。