• SIS Lab
  • >
  • Blog
  • >
  • Stateパターンの実装。InBoxState or OutBoxState 自分の小さな「箱」から脱出する方法

Stateパターンの実装。InBoxState or OutBoxState 自分の小さな「箱」から脱出する方法

更新日:2020.07.05 作成日:2011.08.27

久々に、自分の小さな「箱」から脱出する方法を読み返しました。相変わらず自分を裏切り続ける毎日だなと自己嫌悪に陥りながらも、ちょっとずつ自分を裏切らず、衝動にしたがって動いてもいいかなと。

同時に、プログラムにおいて、状態をうまく表したいときにどうすればいいんだろうかという疑問から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());
    }
    
}

参考図書

増補改訂版Java言語で学ぶデザインパターン入門
増補改訂版Java言語で学ぶデザインパターン入門
出版社:ソフトバンククリエイティブ
著者:結城 浩
発売日: 2004/06/19

Related contents