ほったんはこの記事
なんかすげー気がする!
C#で開発中だし応用したい!
という思いで、色々調べて試してみました。
サンプルアプリの挙動
こんな感じ
コンボボックスで、天気を選択する。
するとそれに応じた言葉が、テキストボックスに表示されます。
ソース
ソースはコチラ!
(はじめてGitHub使った)
ステート追加の仕方
ステートを新たに追加するには
- UI側の追加
- ステート切替の追加
- ステート自体の追加
の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と思われる。
javaは一応わかるものの抽象化等、「THE☆オブジェクト指向」な深いこと(オブジェクト指向的には基礎なのかもしれないが)は詳しくなかった。
ので色々調べてみた。
そこでこの記事に出会った。
なんか分かりやすい!
rubyってまったく知らないんだけど、なんか見やすい!
そこはかとなくpythonとか、PHP(だったかな)辺りと似ているので、なんとなく見たことある雰囲気。
なのでこの、お天気のヤツをコンセプトに作ってみました。
あとがき
改めてGoFのデザインパターンとか、一からちゃんと勉強しようかなとか思いました。
(勉強サボりマンがばれる)