Stateパターンの実装。InBoxState or OutBoxState 自分の小さな「箱」から脱出する方法
移転しました。
同時に、プログラムにおいて、状態をうまく表したいときにどうすればいいんだろう?という疑問からStateパターンに行き着いたので、箱に入った状態と箱から出ている状態をStateパターンで表現してみました。
Stateパターン 状態をクラスとして表現する
「状態」をクラスとして表現していれば、
- クラスを切り替えることによって「状態野変化」があらわせる。
- 新しい状態を追加する際、何をプログラムすればよいかはっきりする。
自分の小さな「箱」から脱出する方法
Stateを実装し、InBoxStateとOutBoxStateを作成。
うーん、こんなんでいいのかな。
自分を裏切ったとき、人は箱に入る
I i = new I(); if( i.betray(myself)){ i.changeState(); } i.getStatus() => "InBox"
箱に入った状態で誰かとしゃべっても自分のことしか考えない。相手を物としか考えない
自分が持つ正当化イメージを守ろうとする。世界は自分を中心に回っていると考えてしまう。
i.talk(); => "think about myself"
箱に入っていることに気付き、相手を一人の人間として接するとき知らぬ間に箱から出ている
if(i.realize()){ i.changeState(); } i.getStatus() => "OutBox" i.talk(); => "think about you"
箱から出て、テストが通ればOK(笑)
コードも心理状態も箱の外のグリーンな気持ちでいつもいれたらいいですね。
package state.box; public interface State { public abstract String talk(); public abstract String feel(); public abstract String getStatus(); public abstract State changeState(); }
package state.box; public class OutBoxState implements State { private static OutBoxState singleton = new OutBoxState(); public static State getInstance() { return singleton; } @Override public String talk() { return "think about you"; } @Override public String feel() { return "calm"; } @Override public String getStatus() { return "OutBox"; } @Override public State changeState() { return InBoxState.getInstance(); } }
package state.box; public class I { private State state = OutBoxState.getInstance(); public String talk() { return state.talk(); } public String getStatus() { return state.getStatus(); } public void changeState() { this.state = state.changeState(); } public String feel(){ return state.feel(); } }
package state.box; public class InBoxState implements State { private static InBoxState singleton = new InBoxState(); public static State getInstance() { return singleton; } @Override public String talk() { return "think about myself"; } @Override public String feel() { return "angry"; } @Override public String getStatus() { return "InBox"; } @Override public State changeState() { return OutBoxState.getInstance(); } }
package test.state.box; import junit.framework.Assert; import org.junit.Test; import state.box.I; public class BoxTest { @Test public void 初期状態は箱の外(){ I i = new I(); Assert.assertEquals("OutBox", i.getStatus()); } @Test public void 自分を裏切ると箱の中に入る(){ I i = new I(); i.changeState(); Assert.assertEquals("InBox", i.getStatus()); } @Test public void 自分が箱に入ってると気づいたとき箱の外に出る(){ I i = new I(); i.changeState(); i.changeState(); Assert.assertEquals("OutBox", i.getStatus()); } @Test public void 箱の外で誰かと話すと相手を一人の人間としてみる(){ I i = new I(); Assert.assertEquals("think about you", i.talk()); } @Test public void 箱に入った状態で誰かと話すと自分のことしか考えない(){ I i = new I(); i.changeState(); Assert.assertEquals("think about myself", i.talk()); } @Test public void 箱の外の気分(){ I i = new I(); Assert.assertEquals("calm", i.feel()); } @Test public void 箱の中の気分(){ I i = new I(); i.changeState(); Assert.assertEquals("angry", i.feel()); } }