lisz-works

技術と興味の集合体

たった3つの手順で拡張できる!ステートパターンで感動できた

【スポンサーリンク】

Visual Studio

ほったんはこの記事

blog.goo.ne.jp

なんかすげー気がする!

C#で開発中だし応用したい!

という思いで、色々調べて試してみました。

サンプルアプリの挙動

こんな感じ

動作サンプル

コンボボックスで、天気を選択する。
するとそれに応じた言葉が、テキストボックスに表示されます。

ソース

ソースはコチラ!
(はじめてGitHub使った)

github.com

ステート追加の仕方

ステートを新たに追加するには

  1. UI側の追加
  2. ステート切替の追加
  3. ステート自体の追加

の3つを行えばOK!

UI側の追加

今回はコンボボックスで、ステータスの切り替えを作成しました。

コンボボックスの要素は、コンストラクタで作成したので、そこに要素を増やします。

これを

// コンボボックスの設定
object[] stateItems = {
    "Sunny", 
    "Rainy",
};

こう

object[] stateItems = {
    "Sunny", 
    "Rainy",
    "Cloudy"    // 追加
};

ステート切替の追加

コンボボックスの変更イベントの要素追加です。

今回は変更後の要素のテキストから、ステートを変更しています。

なので、caseを1つ追加してあげています。

// コンボボックス 要素変更イベント
private void comboState_SelectedIndexChanged(object sender, EventArgs e)
{
    switch ( comboState.SelectedItem.ToString() )
    {
    case "Sunny":
        setEvent(new Sunny());
        break;
    case "Rainy":
        setEvent(new Rainy());
        break;
    // このケースを追加----------------------
    case "Cloudy":
        setEvent(new Cloudy());
        break;
    //--------------------------------------
    default:
        break;
    }
}

ステート自体の追加

他のステートと同様に作りました。

なのでクラス名やテキストを変更しただけです。
動きを知る為の物ですからね。

// このクラスを増やした!
// 曇り
public class Cloudy : State
{
    public Cloudy() { }

    // 抽象クラスを実装=オーバライド
    public override string iceBreak()
    {
        string s = "今日は曇りだ。";
        Console.WriteLine(s);
        return s;
    }
    public override string chooseFastion()
    {
        string s = "いつものスニーカーを履こー。";
        Console.WriteLine(s);
        return s;
    }
}

ステートパターンを実装すると何がいいのか?

本筋の処理を汚したり、肥大化させないというのが、かなりのメリット!

ステートパターンの参考サイトを見ると必ず書かれていますが、ステート管理をしようとすると大概switch文のcaseを増やしていく為、コードが肥大化します。

switch (state)
{
case STATE_A:
    // 処理
    break;
case STATE_B:
    // 処理
    break;
//----ここを追加 ----
case STATE_C:
    // 処理
    break;
//------------------
}

処理の中身が大きいと、その分どんどん長くなっていきます。

1つの分岐の流れで長いと、処理を追うのが大変になります。
対象を見つけるのに膨大なスクロールをしなくちゃいけなくなります。

それ、だるいですよね。

ステートパターンを使うことで、

  • ステートごとの処理は各クラスが持つ
  • クラスを編集すれば修正が完結する

すなわち、修正も追加も楽ちんなのです。神か。

参考

この記事を見るところ、javaと思われる。

blog.goo.ne.jp

javaは一応わかるものの抽象化等、「THE☆オブジェクト指向」な深いこと(オブジェクト指向的には基礎なのかもしれないが)は詳しくなかった。

ので色々調べてみた。

そこでこの記事に出会った。

qiita.com

なんか分かりやすい!

rubyってまったく知らないんだけど、なんか見やすい!

そこはかとなくpythonとか、PHP(だったかな)辺りと似ているので、なんとなく見たことある雰囲気。

なのでこの、お天気のヤツをコンセプトに作ってみました。

C#を攻略しようー抽象クラスー

csharp.sevendays-study.com

takachan.hatenablog.com

あとがき

改めてGoFのデザインパターンとか、一からちゃんと勉強しようかなとか思いました。
(勉強サボりマンがばれる)