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で実装するStateパターン:状態ごとの振る舞いを柔軟に切り替える

Posted at

概要

State(ステート)パターンは、
オブジェクトの内部状態に応じて、振る舞い(メソッドの実装)を動的に変更する設計パターンである。

条件分岐ではなく、「状態をオブジェクトとして定義する」ことで、振る舞いの切り替えを構造化する。


1. なぜStateが必要か?

❌ 状態ごとの振る舞いを if/else で切り替えると煩雑になる

if self.state == "idle":
    ...
elif self.state == "processing":
    ...

状態が増えると条件分岐がスパゲッティ化する


✅ 状態オブジェクトごとに振る舞いを切り出して管理

self.state = ProcessingState()
self.state.handle()

条件分岐不要で状態ごとの処理が明確に分離される


2. 基本構造

✅ Stateインターフェース

class State:
    def handle(self, context):
        raise NotImplementedError

✅ Concrete State(状態ごとの実装)

class IdleState(State):
    def handle(self, context):
        print("現在: Idle → 処理中へ")
        context.set_state(ProcessingState())

class ProcessingState(State):
    def handle(self, context):
        print("現在: Processing → 完了へ")
        context.set_state(CompletedState())

class CompletedState(State):
    def handle(self, context):
        print("現在: Completed → Idleへリセット")
        context.set_state(IdleState())

✅ Context(状態を持つ本体)

class TaskContext:
    def __init__(self):
        self.state = IdleState()

    def set_state(self, state: State):
        self.state = state

    def request(self):
        self.state.handle(self)

✅ 使用例

task = TaskContext()
task.request()  # Idle → Processing
task.request()  # Processing → Completed
task.request()  # Completed → Idle

出力:

現在: Idle → 処理中へ  
現在: Processing → 完了へ  
現在: Completed → Idleへリセット

3. Python的応用:状態を関数やクラスメソッドで表現する柔軟設計

class TrafficLight:
    def __init__(self):
        self._state = self._green

    def _green(self):
        print("青 → 黄")
        self._state = self._yellow

    def _yellow(self):
        print("黄 → 赤")
        self._state = self._red

    def _red(self):
        print("赤 → 青")
        self._state = self._green

    def switch(self):
        self._state()
light = TrafficLight()
for _ in range(4):
    light.switch()

メソッド自体を状態と見なすことで、非常にシンプルに構築可能


4. 実務ユースケース

✅ ワークフローエンジンや承認フローの状態管理

→ 承認・却下・再申請・完了などステート遷移を明確に管理


✅ ゲームのキャラクター状態(待機・攻撃・被弾・死亡)

状態によって入力・挙動を切り替える


✅ UIコンポーネントのモード切替(表示・編集・無効)

→ モードごとの操作制限・表示切替を状態で制御


✅ ネットワーク接続状態(未接続・接続中・切断)

→ 通信状態によって送信処理を制御


5. よくある誤用と対策

❌ 状態遷移が一方向に固定されていて拡張性がない

→ ✅ 遷移を外部で定義 or 状態自身に制御ロジックを持たせる


❌ Contextが状態に強く依存しすぎる

→ ✅ Stateインターフェースを経由し、依存を最小限に保つ


❌ 状態クラスにロジックを詰め込みすぎる

→ ✅ 状態ごとに必要最低限の責務のみを割り当てる


結語

Stateパターンとは、“状態を実装に昇華し、変化を構造として捉える技法”である。

  • 状態ごとに異なる振る舞いをオブジェクト単位で管理
  • 条件分岐から脱却し、柔軟かつ拡張性のあるステート設計を可能にする
  • Pythonではクラス・関数どちらでも簡潔かつ効果的に表現できる

Pythonicとは、“状態変化を自然な構造で扱うこと”。
Stateパターンはその変化の知性を、設計の輪郭に宿す技法である。

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?