🧩 State Pattern
✅ Intent
- Change behavior based on the order status (unconfirmed / confirmed) or processing mode
- Delegate behavior to state-specific objects, each representing a distinct state
✅ Motivation
- The
OrderManager
was responsible for switching behavior based on state - Makes state transitions more explicit and safe
✅ When to Use
- Step-based processes (e.g., wizard-style workflows)
- Logic that varies based on the current state
✅ Code Example
- TypeScript
- PHP
- Python
interface OrderState {
confirm(order: StatefulOrderProcessor): void;
}
class UnconfirmedState implements OrderState {
confirm(order: StatefulOrderProcessor): void {
// 在庫調整・メール送信など
InventoryService.reduce(order.productIds);
EmailService.send(order.userEmail, "注文が確定されました");
OrderLogger.log("order-" + Math.random().toString(36).substring(2));
order.setState(new ConfirmedState());
}
}
class ConfirmedState implements OrderState {
confirm(order: StatefulOrderProcessor): void {
console.log("すでに確定済みです");
}
}
class StatefulOrderProcessor {
private state: OrderState;
constructor(public productIds: string[], public userEmail: string) {
this.state = new UnconfirmedState();
}
setState(state: OrderState) {
this.state = state;
}
confirmOrder() {
this.state.confirm(this);
}
}
// 利用例
const stateProcessor = new StatefulOrderProcessor(
["p01", "p02"],
"hiroshi@example.com"
);
stateProcessor.confirmOrder(); // 初回 → 確定
stateProcessor.confirmOrder(); // 2回目 → 確定済みメッセージ
<?php
interface OrderState {
public function confirm(StatefulOrderProcessor $order): void;
}
class UnconfirmedState implements OrderState {
public function confirm(StatefulOrderProcessor $order): void {
InventoryService::reduce($order->productIds);
EmailService::send($order->userEmail, "注文が確定されました");
OrderLogger::log("order-" . substr(md5((string)mt_rand()), 0, 8));
$order->setState(new ConfirmedState());
}
}
class ConfirmedState implements OrderState {
public function confirm(StatefulOrderProcessor $order): void {
echo "すでに確定済みです\\n";
}
}
class StatefulOrderProcessor {
public OrderState $state;
public array $productIds;
public string $userEmail;
public function __construct(array $productIds, string $userEmail) {
$this->productIds = $productIds;
$this->userEmail = $userEmail;
$this->state = new UnconfirmedState();
}
public function setState(OrderState $state): void {
$this->state = $state;
}
public function confirmOrder(): void {
$this->state->confirm($this);
}
}
// 外部サービス(ダミー)
class InventoryService {
public static function reduce(array $productIds): void {
echo "在庫を " . count($productIds) . " 件分減らしました\\n";
}
}
class EmailService {
public static function send(string $email, string $message): void {
echo "メールを {$email} に送信: {$message}\\n";
}
}
class OrderLogger {
public static function log(string $orderId): void {
echo "注文ログを記録: {$orderId}\\n";
}
}
// 利用例
$processor = new StatefulOrderProcessor(["p01", "p02"], "hiroshi@example.com");
$processor->confirmOrder(); // 初回:確定
$processor->confirmOrder(); // 2回目:すでに確定済み
import random
import string
from abc import ABC, abstractmethod
# 状態インターフェース
class OrderState(ABC):
@abstractmethod
def confirm(self, order: "StatefulOrderProcessor"):
pass
# 状態クラス:未確定
class UnconfirmedState(OrderState):
def confirm(self, order: "StatefulOrderProcessor"):
InventoryService.reduce(order.product_ids)
EmailService.send(order.user_email, "注文が確定されました")
order_id = "order-" + ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
OrderLogger.log(order_id)
order.set_state(ConfirmedState())
# 状態クラス:確定済み
class ConfirmedState(OrderState):
def confirm(self, order: "StatefulOrderProcessor"):
print("すでに確定済みです")
# コンテキスト
class StatefulOrderProcessor:
def __init__(self, product_ids: list[str], user_email: str):
self.product_ids = product_ids
self.user_email = user_email
self.state: OrderState = UnconfirmedState()
def set_state(self, state: OrderState):
self.state = state
def confirm_order(self):
self.state.confirm(self)
# 外部サービス(ダミー)
class InventoryService:
@staticmethod
def reduce(product_ids: list[str]):
print(f"在庫を {len(product_ids)} 件分減らしました")
class EmailService:
@staticmethod
def send(email: str, message: str):
print(f"メールを {email} に送信: {message}")
class OrderLogger:
@staticmethod
def log(order_id: str):
print(f"注文ログを記録: {order_id}")
# 利用例
processor = StatefulOrderProcessor(["p01", "p02"], "hiroshi@example.com")
processor.confirm_order() # 初回:確定
processor.confirm_order() # 2回目:すでに確定済み
✅ Explanation
This code applies the State
pattern to switch behavior based on the current order status (unconfirmed or confirmed).
The State
pattern encapsulates state-dependent behavior within separate classes, allowing the system to transition between states in a controlled manner.
1. Overview of the State Pattern
- The following state classes are implemented based on the
OrderState
interface:UnconfirmedState
: Represents an order that has not yet been confirmedConfirmedState
: Represents an already confirmed order
2. Key Classes and Their Roles
-
OrderState
interface- Defines the interface for state-specific behavior
- Requires implementation of the
confirm(order: StatefulOrderProcessor): void
method
-
UnconfirmedState
- Represents the unconfirmed state of an order
- The
confirm
method performs the following:- Reduces inventory
- Sends a confirmation email to the user
- Logs the order
- Transitions the state to
ConfirmedState
-
ConfirmedState
- Represents a confirmed order
- The
confirm
method outputs a message indicating the order is already confirmed
-
StatefulOrderProcessor
- Context class that manages the current state
- Holds the current state and delegates the
confirmOrder
method to the active state - State transitions are handled via the
setState
method
3. UML Class Diagram
4. Benefits of the State Pattern
- Behavior is clearly separated by state: Each state's logic is self-contained, improving readability and maintainability
- Explicit state transitions: Changes in state are clearly controlled through the
setState
method - Extensibility: New states can be added by implementing the
OrderState
interface
This design clearly separates state-dependent behavior and ensures safe and manageable state transitions.