🧩 Command Pattern
✅ Intent
- Represent executable actions as command objects
- Execute different behaviors depending on the command, not the internal state
✅ Motivation
- Useful when the focus is on substituting what gets executed, rather than managing internal state
- Especially effective in cases involving operation history, Undo/Redo, or deferred execution
✅ Code Example
- TypeScript
- PHP
- Python
// コマンドインターフェース
interface PublishCommand {
execute(): void;
}
// 各状態の処理をコマンド化
class DraftPublishCommand implements PublishCommand {
execute(): void {
console.log("レビュー依頼を送信");
}
}
class ReviewPublishCommand implements PublishCommand {
execute(): void {
console.log("公開しました");
}
}
class PublishedPublishCommand implements PublishCommand {
execute(): void {
console.log("すでに公開済みです");
}
}
// Invoker(呼び出し役)
class Document {
private command: PublishCommand;
constructor(command: PublishCommand) {
this.command = command;
}
setCommand(command: PublishCommand): void {
this.command = command;
}
publish(): void {
this.command.execute();
}
}
// 利用例
const doc = new Document(new DraftPublishCommand());
doc.publish(); // → レビュー依頼
doc.setCommand(new ReviewPublishCommand());
doc.publish(); // → 公開
doc.setCommand(new PublishedPublishCommand());
doc.publish(); // → すでに公開済み
<?php
interface PublishCommand {
public function execute(): void;
}
class DraftPublishCommand implements PublishCommand {
public function execute(): void {
echo "レビュー依頼を送信\n";
}
}
class ReviewPublishCommand implements PublishCommand {
public function execute(): void {
echo "公開しました\n";
}
}
class PublishedPublishCommand implements PublishCommand {
public function execute(): void {
echo "すでに公開済みです\n";
}
}
class Document {
private PublishCommand $command;
public function __construct(PublishCommand $command) {
$this->command = $command;
}
public function setCommand(PublishCommand $command): void {
$this->command = $command;
}
public function publish(): void {
$this->command->execute();
}
}
// 利用例
$doc = new Document(new DraftPublishCommand());
$doc->publish();
$doc->setCommand(new ReviewPublishCommand());
$doc->publish();
$doc->setCommand(new PublishedPublishCommand());
$doc->publish();
from abc import ABC, abstractmethod
class PublishCommand(ABC):
@abstractmethod
def execute(self):
pass
class DraftPublishCommand(PublishCommand):
def execute(self):
print("レビュー依頼を送信")
class ReviewPublishCommand(PublishCommand):
def execute(self):
print("公開しました")
class PublishedPublishCommand(PublishCommand):
def execute(self):
print("すでに公開済みです")
class Document:
def __init__(self, command: PublishCommand):
self._command = command
def set_command(self, command: PublishCommand):
self._command = command
def publish(self):
self._command.execute()
# 利用例
doc = Document(DraftPublishCommand())
doc.publish()
doc.set_command(ReviewPublishCommand())
doc.publish()
doc.set_command(PublishedPublishCommand())
doc.publish()
✅ Explanation
This code applies the Command
pattern to encapsulate the document publishing logic as commands that can be switched dynamically.
The Command
pattern encapsulates an operation as an object, enabling delayed execution, flexible substitution, and reuse.
1. Overview of the Command Pattern
-
Command: Defines the interface for encapsulated operations
- Represented by
PublishCommand
- Represented by
-
ConcreteCommand: Implements the command interface with specific operations
- Represented by
DraftPublishCommand
,ReviewPublishCommand
, andPublishedPublishCommand
- Represented by
-
Invoker: Responsible for executing the command
- Represented by
Document
- Represented by
-
Client: Creates the appropriate command and passes it to the invoker
- Represented by
new Document(new DraftPublishCommand())
in this code
- Represented by
2. Key Classes and Their Roles
-
PublishCommand
- Common interface for publishing commands
- Declares the method
execute(): void
-
DraftPublishCommand
,ReviewPublishCommand
,PublishedPublishCommand
- Concrete command classes implementing
PublishCommand
- Each class provides a different publishing behavior:
DraftPublishCommand
: Sends a review requestReviewPublishCommand
: Publishes the documentPublishedPublishCommand
: Indicates the document is already published
- Concrete command classes implementing
-
Document
- The invoker class
- Accepts a
PublishCommand
via its constructor and executes it through thepublish
method - Allows dynamic command replacement via the
setCommand
method
3. UML Class Diagram
4. Benefits of the Command Pattern
- Encapsulation of Operations: Encapsulates actions as objects for deferred or dynamic execution
- Flexibility: New operations can be added simply by implementing
PublishCommand
- Reusable Invoker: The
Document
class can execute any command, making it highly reusable
This design treats behavior as a first-class object, improving flexibility and extensibility.
It is especially effective when you need to switch operations or manage execution history.