Featured image of post Stateパターン調査ドキュメント

Stateパターン調査ドキュメント

Stateパターン(状態パターン)に関する調査結果。定義、ユースケース、実装例、競合記事分析、内部リンク調査

Stateパターン調査ドキュメント

調査概要

  • 調査目的: Stateパターンの技術情報、実装例、ユースケースを調査し、記事作成の基礎資料を作成する
  • 調査実施日: 2026年1月8日
  • キーワード: Stateパターン、State pattern、デザインパターン、GoF
  • 技術スタック: Perl / Moo

1. Stateパターンの基礎

1.1 定義と目的

要点:

  • Stateパターンは、GoF(Gang of Four)の振る舞いパターン(Behavioral Patterns)の1つ
  • 「オブジェクトの内部状態が変化したときに、その振る舞いを変化させる。オブジェクトはあたかもクラスを変えたかのように振る舞う」
  • オブジェクトの状態に応じて振る舞いを切り替えることを可能にする
  • 状態ごとの条件分岐(if/else、switch)を削減し、状態をオブジェクトとして分離する

根拠:

  • GoF書籍「Design Patterns: Elements of Reusable Object-Oriented Software」(1994年)で定義
  • Refactoring Guru、GeeksforGeeks、Wikipedia等の主要技術サイトで一致した説明

仮定:

  • 読者はStrategyパターンを学習済み、または並行して学習中
  • 「状態」と「振る舞い」の関係を理解する必要がある

出典:

信頼度: 9/10(GoF原典および複数の信頼できる技術サイト)


1.2 構成要素(State、ConcreteState、Context)

Stateパターンは、以下の3つの主要コンポーネントで構成される。

	classDiagram
    class Context {
        -state: State
        +setState(State)
        +request()
    }
    class State {
        <<interface>>
        +handle(Context)
    }
    class ConcreteStateA {
        +handle(Context)
    }
    class ConcreteStateB {
        +handle(Context)
    }
    class ConcreteStateC {
        +handle(Context)
    }
    
    Context o--> State : has
    ConcreteStateA ..|> State : implements
    ConcreteStateB ..|> State : implements
    ConcreteStateC ..|> State : implements
要素役割Perl/Moo実装での具体例
State(状態インターフェース)共通の状態インターフェースを定義。すべての具象状態が実装すべきメソッドを宣言VendingMachineState(Moo::Role、requires 'handle'
ConcreteState(具象状態)Stateインターフェースを実装し、その状態での具体的な振る舞いと状態遷移ロジックを提供WaitingState, CoinInsertedState, DispensingState
Context(文脈)現在のStateオブジェクトへの参照を保持し、クライアントにインターフェースを提供。状態変更を受け付けるVendingMachine(has state => …)

要点:

  • Contextは状態の詳細を知らない(疎結合)
  • ConcreteStateがContextへの参照を持ち、状態遷移を制御することが多い(Strategyとの重要な違い)
  • 状態遷移ロジックは各ConcreteStateに分散される

根拠:

  • GoF書籍の構造定義
  • TECHSCORE、IT専科等のデザインパターン解説サイト

出典:

信頼度: 9/10


1.3 メリット・デメリット

メリット

メリット説明実践的な効果
条件分岐の削減・コード可読性の向上if/switchが減り、コードがシンプルで読みやすくなる保守性向上
状態ごとの責務が明確各状態クラスがその状態に特化した振る舞いだけを担当(SRP準拠)変更影響範囲の限定
状態追加・修正が容易新しい状態を追加しても既存クラスに手を加えなくて済む(OCP準拠)機能拡張が容易
状態遷移の明確化状態遷移ロジックが各状態クラスに局所化されるバグの発見・修正が容易
ユニットテストがしやすい各状態ごとのテストが独立して書きやすいテスト容易性

デメリット

デメリット説明対策
クラス数が増える状態ごとにクラスを設けるため、シンプルな処理には不向き状態数が少ない場合は適用を見送る
設計・初学者への理解コスト小規模な状態管理ならif/switchの方が直感的適用判断を慎重に
状態遷移の管理の手間状態変更ロジックが複雑になる場合、パターンだけでは不十分状態遷移図との併用
状態間の共有データ管理状態間で共有するデータの受け渡しが複雑になる可能性Contextで一元管理

根拠:

  • 複数の技術記事・Stack Overflowでの議論
  • Qiita、Zenn等での実践報告

出典:

信頼度: 9/10


1.4 Stateパターンが有効なユースケース

要点:

適用シーン説明具体例
状態遷移が明確なシステム有限状態オートマトン(FSM)として表現できる自動販売機、信号機、ATM
状態による振る舞いの大きな変化同じ操作でも状態によって結果が全く異なるゲームキャラクターのモード
状態遷移ルールの存在特定の状態からしか遷移できない条件があるワークフロー、承認フロー
if/elseの肥大化状態に応じた条件分岐が複雑化しているレガシーコードのリファクタリング

適用すべきでない場面:

  • 状態が1〜2個で今後も増えない見込み
  • 状態間の差異がほとんどない
  • 状態遷移ルールがシンプルで固定的
  • 追加クラスによる複雑さがメリットを上回る

信頼度: 9/10


2. 類似パターンとの比較

2.1 Stateパターン vs Strategyパターンの違い

項目StateパターンStrategyパターン
目的オブジェクトの状態に応じて振る舞いを変えるアルゴリズムを切り替える
変更の主体オブジェクト自身が内部状態に応じて変更クライアント(外部)が選択
状態遷移あり(状態間の遷移ルールが存在)なし(独立したアルゴリズム選択)
Contextへの参照StateはContextへの参照を持つことが多いStrategyは通常Contextを知らない
典型例自動販売機の状態、TCP接続の状態ソートアルゴリズム、支払い方法
切り替えトリガー内部状態の変化に応じて自動外部から明示的に指定

選択指針:

  • 「オブジェクトの状態によって振る舞いを変えたい」+「状態遷移がある」State
  • 「どう処理するか(アルゴリズム)を切り替えたい」+「外部から選択」Strategy

根拠:

  • GoF書籍での定義
  • 両パターンの構造は似ているが、意図と責任が異なる

出典:

信頼度: 9/10


2.2 他の振る舞いパターンとの関係

パターンStateとの関係使い分け
Strategy構造が類似。目的と切り替え主体が異なる状態遷移あり→State、アルゴリズム選択→Strategy
Command操作のカプセル化。Undo/Redo対応操作履歴が必要→Command
Observer状態変化の通知に併用可能状態変化を外部に通知したい場合に組み合わせ
Template Method継承ベースでアルゴリズムの骨格を定義骨格固定でステップ変更→Template Method

信頼度: 9/10


3. Stateパターンの実装例

3.1 一般的な実装パターン

信号機の例(状態遷移図)

1
2
3
[赤信号] --(時間経過)--> [青信号]
[青信号] --(時間経過)--> [黄信号]
[黄信号] --(時間経過)--> [赤信号]

Javaでの基本実装例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// State インターフェース
public interface TrafficLightState {
    void showSignal();
    void next(TrafficLight trafficLight);
}

// ConcreteState: 赤信号
public class RedState implements TrafficLightState {
    @Override
    public void showSignal() {
        System.out.println("赤信号:止まってください");
    }
    @Override
    public void next(TrafficLight trafficLight) {
        trafficLight.setState(new GreenState());
    }
}

// ConcreteState: 青信号
public class GreenState implements TrafficLightState {
    @Override
    public void showSignal() {
        System.out.println("青信号:進んでください");
    }
    @Override
    public void next(TrafficLight trafficLight) {
        trafficLight.setState(new YellowState());
    }
}

// Context
public class TrafficLight {
    private TrafficLightState currentState;
    
    public TrafficLight() {
        this.currentState = new RedState();
    }
    
    public void setState(TrafficLightState state) {
        this.currentState = state;
    }
    
    public void showSignal() {
        currentState.showSignal();
    }
    
    public void change() {
        currentState.next(this);
    }
}

出典:

信頼度: 9/10


3.2 Perlでの実装アプローチ(Moo/Mooseを使った場合)

要点:

  • PerlではMoo::Roleを「State インターフェース」として使用
  • requiresで必須メソッドを定義し、各ConcreteStateクラスがRoleを消費(with)
  • StateがContextへの参照を持ち、状態遷移を制御する

コード例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
# State Role(インターフェース)
package VendingMachineState;
use Moo::Role;
requires 'insert_coin';
requires 'select_product';
requires 'dispense';
1;

# ConcreteState A: 待機状態
package WaitingState;
use Moo;
use v5.36;
with 'VendingMachineState';

sub insert_coin ($self, $context) {
    say "コインを受け付けました";
    $context->set_state(CoinInsertedState->new);
}

sub select_product ($self, $context) {
    say "先にコインを入れてください";
}

sub dispense ($self, $context) {
    say "商品を払い出せません";
}
1;

# ConcreteState B: コイン投入済み状態
package CoinInsertedState;
use Moo;
use v5.36;
with 'VendingMachineState';

sub insert_coin ($self, $context) {
    say "既にコインが入っています";
}

sub select_product ($self, $context) {
    say "商品を選択しました";
    $context->set_state(DispensingState->new);
}

sub dispense ($self, $context) {
    say "先に商品を選んでください";
}
1;

# ConcreteState C: 払い出し状態
package DispensingState;
use Moo;
use v5.36;
with 'VendingMachineState';

sub insert_coin ($self, $context) {
    say "払い出し中です。お待ちください";
}

sub select_product ($self, $context) {
    say "払い出し中です。お待ちください";
}

sub dispense ($self, $context) {
    say "商品を払い出しました";
    $context->set_state(WaitingState->new);
}
1;

# Context: 自動販売機
package VendingMachine;
use Moo;
use v5.36;

has state => (
    is      => 'rw',
    default => sub { WaitingState->new },
);

sub set_state ($self, $state) {
    $self->state($state);
}

sub insert_coin ($self) {
    $self->state->insert_coin($self);
}

sub select_product ($self) {
    $self->state->select_product($self);
}

sub dispense ($self) {
    $self->state->dispense($self);
}
1;

# 使用例
package main;
use v5.36;

my $machine = VendingMachine->new;
$machine->insert_coin;      # コインを受け付けました
$machine->select_product;   # 商品を選択しました
$machine->dispense;         # 商品を払い出しました
$machine->select_product;   # 先にコインを入れてください

根拠:

  • Moo::Roleのrequiresで必須メソッドを宣言でき、実装漏れを防げる
  • Strategyパターンとの違い:StateがContext($self)を受け取り、状態遷移を制御する

出典:

信頼度: 9/10


4. 競合記事の分析

4.1 日本語の主要記事

記事タイトルURL特徴差別化ポイント
デザインパターン Stateパターン(Qiita)https://qiita.com/AsahinaKei/items/ce8e5d7bc375af23c719エアコン制御の実例、Java中心Java特化、Perl非対応
GoF 23パターン State編(Qiita)https://qiita.com/Pentaro256/items/752f28aa425c4295b13dGoF準拠、体系的解説網羅的だが実践例少なめ
今さら聞けないステートパターン(Zenn)https://zenn.dev/nekoniki/articles/b039e5e553b5e95729b5TypeScript実装、犬の状態例Web系向け、Perl非対応
デザインパターンを学ぶ #17 ステート(Zenn)https://zenn.dev/tajicode/articles/aa18feba9a570f段階的解説、初心者向けPerl非対応
State パターン(TECHSCORE)https://www.techscore.com/tech/DesignPattern/State入門向け、シンプル古い記事、モダン言語非対応
State パターン(IT専科)https://www.itsenka.com/contents/development/designpattern/state.html基本解説実装例が少ない
State(Refactoring Guru 日本語)https://refactoring.guru/ja/design-patterns/state図解豊富、多言語対応Perl無し

4.2 差別化ポイントの抽出

既存記事の問題点:

  1. Perl/Moo特化の記事が皆無: 日本語でPerl向けのState解説はほぼ存在しない
  2. Strategyとの比較が不十分: 構造が似ているため混同しやすいが、違いの説明が曖昧
  3. 状態遷移図との連携不足: コードだけで状態遷移を説明しがち
  4. 実践的なユースケースの不足: 抽象的な例が多い

本教材シリーズの強み(予定):

  1. Perl/Moo特化: v5.36対応のモダンPerl記法
  2. Strategyパターンとの明確な比較: 既存のStrategyシリーズとの連携
  3. 状態遷移図との併用: Mermaidで視覚化
  4. 段階的な学習: 「Mooで覚えるオブジェクト指向プログラミング」からの継続性
  5. 実践的な題材: 自動販売機など身近な例

信頼度: 9/10


5. 内部リンク調査

5.1 関連記事(grep調査結果)

State/ステート関連のヒット

ファイルパス内部リンク関連度
/content/post/2026/01/09/005327.md/2026/01/09/005327/高(Strategyシリーズ最終回でStateに言及)
/content/post/2026/01/08/033715.md/2026/01/08/033715/要確認
/content/post/2026/01/08/033309.md/2026/01/08/033309/要確認
/content/post/2026/01/08/033512.md/2026/01/08/033512/要確認

Strategy/ストラテジー関連のヒット(比較用)

ファイルパス内部リンク関連度
/content/post/2026/01/09/005327.md/2026/01/09/005327/最高(Strategyパターン解説記事)
/content/post/2026/01/03/001541.md/2026/01/03/001541/高(ディスパッチャーシリーズ最終回)
/content/post/2025/12/07/000000.md/2025/12/07/000000/中(Test2フレームワーク内でstrategy設定)

デザインパターン関連のヒット

ファイルパス内部リンク関連度
/content/post/2025/12/25/234500.md/2025/12/25/234500/
/content/post/2026/01/04/011446.md - /content/post/2026/01/04/011452.md複数高(デザインパターン関連シリーズ)

Moo/オブジェクト指向関連のヒット

ファイルパス内部リンク関連度
/content/post/2025/12/11/000000.md/2025/12/11/000000/最高(Moo/Moose解説記事)
/content/post/2025/12/30/163810.md - /content/post/2025/12/30/163820.md複数高(「Mooで覚えるOOP」シリーズ全12回)

5.2 推奨内部リンク一覧

前提知識記事

記事内部リンクリンク理由
Moo/Moose解説/2025/12/11/000000/Moo::Roleの前提知識
Mooで覚えるOOP 第10回(ロール)/2025/12/30/163818/Moo::Role、withの詳細
Mooで覚えるOOP 第7回(関連するデータ)/2025/12/30/163815/オブジェクトの関連(ContextがStateを持つ)
Mooで覚えるOOP 第12回(型チェック)/2025/12/30/163820/does制約

比較・関連記事

記事内部リンクリンク理由
Strategyパターン解説(データエクスポーター最終回)/2026/01/09/005327/Strategyとの比較
ディスパッチャーシリーズ最終回/2026/01/03/001541/Strategyパターンとの関連
デザインパターン概要/warehouse/design-patterns-overview/GoFパターン全体像

6. 既存シリーズとの重複チェック

6.1 /agents/structure/ 配下の既存シリーズ構造

ファイル名内容Stateパターンとの重複
strategy-pattern-series-structure.mdStrategyパターンシリーズ構造案関連あり(比較対象)
moo-oop-series-structure.mdMooで覚えるOOPシリーズ構造案前提知識シリーズ
moo-dispatcher-series-structure.mdディスパッチャーシリーズ構造案Strategyパターン実践(別題材)
command-pattern-series-structure.mdCommandパターンシリーズ構造案振る舞いパターン(別パターン)
singleton-pattern-series-structure.mdSingletonパターンシリーズ構造案生成パターン(別カテゴリ)
facade-pattern-series-structure.mdFacadeパターンシリーズ構造案構造パターン(別カテゴリ)
adapter-pattern-series-structure.mdAdapterパターンシリーズ構造案構造パターン(別カテゴリ)
iterator-pattern-series-structure.mdIteratorパターンシリーズ構造案振る舞いパターン(別パターン)

6.2 重複チェック結果

Stateパターンを扱った既存シリーズ: なし

既存のシリーズ構造案にStateパターンを主題としたものは存在しない。


7. まとめ

7.1 調査結果のサマリー

  1. Stateパターンの位置づけ: GoF振る舞いパターンの1つ。Strategyパターンと構造は似ているが、目的と切り替え主体が異なる

  2. Strategyとの主な違い:

    • State: 内部状態の変化に応じて自動で切り替え、状態遷移あり
    • Strategy: 外部から明示的にアルゴリズムを選択
  3. Perl/Moo実装の可能性: Moo::Roleで状態インターフェースを定義し、各ConcreteStateがContextへの参照を持って状態遷移を制御する設計が可能

  4. 既存シリーズとの重複: Stateパターンを扱った既存シリーズはなし


参考文献・リソースリスト

書籍

書籍名著者ISBN/ASIN重要度
Design Patterns: Elements of Reusable Object-Oriented SoftwareGoF978-0201633610必須
Head First Design Patterns (2nd Edition)Eric Freeman, Elisabeth Robson978-1492078005推奨

Webリソース

リソース名URL特徴信頼度
Refactoring Guru - State(日本語)https://refactoring.guru/ja/design-patterns/state視覚的な図解、多言語コード例★★★★★
Wikipedia - State patternhttps://en.wikipedia.org/wiki/State_pattern正式な定義★★★★★
Qiita - デザインパターン Stateパターンhttps://qiita.com/AsahinaKei/items/ce8e5d7bc375af23c719Java実装例★★★★☆
Qiita - GoF 23パターン State編https://qiita.com/Pentaro256/items/752f28aa425c4295b13d体系的解説★★★★☆
Zenn - ステートパターンhttps://zenn.dev/nekoniki/articles/b039e5e553b5e95729b5TypeScript実装★★★★☆
TECHSCORE - State パターンhttps://www.techscore.com/tech/DesignPattern/State入門向け★★★★☆
MetaCPAN - Moohttps://metacpan.org/pod/MooPerl Moo公式★★★★★
MetaCPAN - Moo::Rolehttps://metacpan.org/pod/Moo::RolePerl Moo::Role公式★★★★★

調査完了日: 2026年1月8日 調査者: 調査・情報収集エージェント


End of Document

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。