【デザインパターン】【GoF】【C#】ストラテージ(Strategy)パターン

Strategyパターンとは?

 * プログラムの実行時にアルゴリズム(処理の戦略)を切り替えることができるパターン
 * アルゴリズム(処理の戦略)を何通りか用意し、状況に応じて切り替えられる

Strategy パターンの UML クラス図は、Bridge パターンと同じであるが、Strategy パターンは 振る舞い に対するパターンであるが、Bridge パターンは 構造 に対するパターンであって、意図が異なる。

利点

 * クラスを使う側のコードを変更することなく、アルゴリズムを変更することができる点

サンプル

構成

 1) 状態クラス (特徴として、状態を示すスーパークラスもしくはインターフェイス/Stateを作成し、継承する)
 2) 状態を切り替えるクラス(StateManagerクラス)
 3) 状態クラスを仲介するクラス(Mediatorクラス)

適用前

enum DayState
{
    Mornig,
    Afternoon,
    Night,
}

private string SayGreating(DayState state)
{
    string returnValue;

    switch (state)
    {
        case DayState.Mornig:
            // 処理A
            returnValue = "Good Mornig";
            break;
        case DayState.Afternoon:
            // 処理B
            returnValue = "Good Afternoon";
            break;
        case DayState.Night:
            // 処理C
            returnValue = "Good Night";
            break;
        default:
            throw new  ArgumentException();
    }
}

適用後

* 今回の例では、ありがたみは感じないが、処理が長かったら、非常に見やすくなりそう。
* インターフェイスで行っているところがミソな感じがする
enum DayState
{
    Mornig,
    Afternoon,
    Night,
}

// [1] インタフェースとして作成する
interface SampleState
{
    string GetGreating();
}

// [2] インタフェースを適用したクラスを作成して、条件に合わせた処理を実装する
class Morning : SampleState
{
    string GetGreating()
    {
        return "Good Mornig";
    }
}

class Afternoon : SampleState
{
    string GetGreating()
    {
        return "Good Afternoon";
    }
}

class Night : SampleState
{
    string GetGreating()
    {
        return "Good Night";
    }
}

// 使用時に、条件によってアルゴリズムクラスを生成する。
private string SayGreating(DayState state)
{
    SampleState sample;

    switch (state)
    {
        case DayState.Mornig:
            sample = new Morning();
            break;
        case DayState.Afternoon:
            sample = new Afternoon();
            break;
        case DayState.Night:
            sample = new Night();
            break;
        default:
            throw new  ArgumentException();
    }

    return sample.GetGreating();
}

例2

* こんな感じでもあり
SampleState moring = new Morning();
SampleState afternoon = new Afternoon();
SampleState night = new Night();

private string SayGreating()
{
    SampleState sample;

    // 処理・・・
    if (条件1)
        sample = moring;
    // 処理・・・

    return sample.GetGreating();
}


関連記事

Stateパターン

http://blogs.yahoo.co.jp/dk521123/22473711.html