0
1

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(コマンド)パターンは、
アクション(命令)をオブジェクトとして抽象化し、実行・取消・履歴管理を柔軟に制御できるようにする設計パターンである。

UI操作、マクロ、Undo/Redo、タスクスケジューリングなどに非常に適しており、“何をするか”をデータとして扱えるのが強み。


1. なぜCommandが必要か?

❌ 操作がイベントハンドラに直書きされて複雑化

def on_click():
    db.save()
    ui.refresh()
    logger.log("saved")

→ 処理が肥大化し、再利用や履歴記録が困難に


✅ 処理をCommandオブジェクトとして切り出し、実行・管理を分離

command = SaveCommand(db, ui, logger)
command.execute()

処理単位をオブジェクトとして扱える構造に変換


2. 基本構造

✅ Commandインターフェース

class Command:
    def execute(self):
        raise NotImplementedError

    def undo(self):
        raise NotImplementedError

✅ Concrete Command(処理の実装)

class SaveCommand(Command):
    def __init__(self, db, ui, logger):
        self.db = db
        self.ui = ui
        self.logger = logger

    def execute(self):
        self.db.save()
        self.ui.refresh()
        self.logger.log("保存完了")

    def undo(self):
        self.db.rollback()
        self.ui.refresh()
        self.logger.log("保存取り消し")

✅ Invoker(命令を使う側)

class CommandManager:
    def __init__(self):
        self._history = []

    def run(self, command):
        command.execute()
        self._history.append(command)

    def undo(self):
        if self._history:
            command = self._history.pop()
            command.undo()

✅ 使用例

command = SaveCommand(db, ui, logger)
manager = CommandManager()

manager.run(command)
manager.undo()

3. Python的応用:関数・クロージャでCommandを表現する

class FunctionCommand(Command):
    def __init__(self, func, undo_func):
        self.func = func
        self.undo_func = undo_func

    def execute(self):
        self.func()

    def undo(self):
        self.undo_func()
cmd = FunctionCommand(
    lambda: print("実行処理"),
    lambda: print("取り消し処理")
)
cmd.execute()
cmd.undo()

関数型スタイルとの親和性も高く、柔軟に拡張できる


4. 実務ユースケース

✅ GUI操作におけるコマンド(コピー、削除、貼り付け等)

→ 各アクションをCommandとして実装し、Undo/Redoを可能に


✅ バッチ処理やスケジューラにおけるタスク管理

遅延実行やキューイングを構造的に表現


✅ マクロ機能の記録・再実行

→ 実行されたCommandの履歴を保存・再生


✅ CLI/RESTなどの抽象化された操作層の設計

→ 各API操作をCommandとして定義し、統一インターフェースを提供


5. よくある誤用と対策

❌ Commandオブジェクトに過剰な責務が集中する

→ ✅ 単一責任原則を守り、1つのCommandに1つの処理を


❌ 実行と取り消しの副作用が対称でない

→ ✅ undoの意味と保証範囲を明確に設計すること


❌ 状態管理(履歴や失敗復旧)が設計に含まれていない

→ ✅ CommandManager等を使って履歴管理・例外対応を構造に組み込む


結語

Commandパターンとは、“命令をオブジェクトとして抽象化し、実行をコントロールする構造”である。

  • アクションをオブジェクト化し、再利用・取り消し・記録が可能に
  • 実行の詳細を隠蔽しながら、柔軟な操作制御を実現
  • Pythonでは関数・クラス・クロージャを活用し、極めて簡潔に表現できる

Pythonicとは、“処理をデータとして扱う柔らかさ”。
Commandパターンはその柔軟性と構造化の美を、命令という抽象に込める技法である。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?