2
3

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(ステート)パターンは、
オブジェクトの状態が変化するたびに、そのオブジェクトの振る舞いも変化するように構造化するパターンである。

条件分岐(if-elifswitch-case)を多用するコードを整理し、
状態ごとに明確なクラスを定義することで、状態遷移と振る舞いの責務を分離し、保守性と拡張性を高める。


1. なぜStateパターンが必要か?

❌ 状態管理を条件分岐で処理

if self.state == "draft":
    self.save_as_draft()
elif self.state == "published":
    self.publish()

→ 状態が増えるごとに分岐が膨張し、メンテナンス困難に


✅ 各状態をクラスとして独立定義

post.set_state(DraftState())
post.save()  # 状態オブジェクトに処理を委譲

振る舞いの委譲により、ロジックを状態ごとに分離可能


2. 基本構造

✅ 状態インタフェース

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

✅ 状態の具象クラス

class DraftState(State):
    def save(self, context):
        print("Saving as draft...")

class PublishedState(State):
    def save(self, context):
        print("Already published. No save needed.")

✅ コンテキストクラス(状態保持者)

class Post:
    def __init__(self):
        self._state = DraftState()

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

    def save(self):
        self._state.save(self)

✅ 使用例

post = Post()
post.save()  # → Saving as draft...

post.set_state(PublishedState())
post.save()  # → Already published. No save needed.

3. Python的応用:動的遷移・イベントベース設計

class ApprovedState(State):
    def save(self, context):
        print("Cannot save. This is already approved.")
        context.set_state(ArchivedState())

class ArchivedState(State):
    def save(self, context):
        print("Archived. Read-only.")

→ 状態が内部で他の状態へ自律的に遷移できる


4. 実務ユースケース

✅ コンテンツ管理システムの投稿状態管理

  • Draft / Review / Published / Archived などの状態ごとの動作を分離

✅ UIコンポーネントのモード遷移(例:ボタン)

  • enabled, disabled, hovered, pressed 状態ごとのビヘイビアを状態クラスで制御

✅ ゲーム内キャラクターの状態管理

  • idle, running, attacking, damaged のような行動状態に応じた処理の切替

✅ フロー制御、ワークフローのステップ管理

  • 承認・却下・差し戻しなどを、状態クラスとして明示的に定義

5. よくある誤用と対策

❌ コンテキストクラスが状態ごとの振る舞いを保持してしまう

→ ✅ 各状態に処理を完全に委譲し、コンテキストはただの受け皿に徹する


❌ 状態クラスがコンテキストに依存しすぎる

→ ✅ 状態は独立した振る舞い定義に徹し、遷移や副作用のみ必要に応じて利用


❌ 状態が増えたときのクラス爆発

→ ✅ 状態を抽象化・再利用可能に設計し、DRY原則を意識


結語

Stateパターンとは、“状態による振る舞いの変化を設計上の構造で明示する”ためのパターンである。

  • 分岐ロジックを状態クラスに分離し、高凝集・低結合な設計を実現
  • 状態の増減に耐えうる柔軟性を備え、コードのスケーラビリティを向上
  • Pythonの動的性とシンプルな構文が、Stateパターンの実装をより直感的にしてくれる

Pythonicとは、“動的な変化を構造で整理する”ことであり、
Stateパターンはその整理された変化の設計を、柔軟性と拡張性の核に据える技法である。

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?