🧩 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 OrderManagerwas 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 OrderStateinterface:- UnconfirmedState: Represents an order that has not yet been confirmed
- ConfirmedState: Represents an already confirmed order
 
2. Key Classes and Their Roles
- 
OrderStateinterface- Defines the interface for state-specific behavior
- Requires implementation of the confirm(order: StatefulOrderProcessor): voidmethod
 
- 
UnconfirmedState- Represents the unconfirmed state of an order
- The confirmmethod 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 confirmmethod outputs a message indicating the order is already confirmed
 
- 
StatefulOrderProcessor- Context class that manages the current state
- Holds the current state and delegates the confirmOrdermethod to the active state
- State transitions are handled via the setStatemethod
 
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 setStatemethod
- Extensibility: New states can be added by implementing the OrderStateinterface
This design clearly separates state-dependent behavior and ensures safe and manageable state transitions.