State? なのかどうなのか

進む、戻る、な状態遷移な実装を、という事で微妙な紙芝居実装をでっち上げてみたので検証がてら (?) メモを控えておきます。

interface

とりあえず行き戻りができる、という事で以下なカンジに。

public interface IState {
	void initialize();
	void display();
}

実は Android なので

  • initialize で View を拾って callback の設定など
  • display とは名前ばかりで戻る場合の再表示なのかどうか

という形。変更かける可能性は非常に高いです。
で、この状態遷移のスタート地点になってる Activity ではある契機で State パターンで言う Context なオブジェクトを生成してヨーイドンしてます。

        mStateTransition = new StateTransition(this);
        mStateTransition.kickoff();

で、この Context なクラスなのですが

public class StateTransition {
    
    private HogeActivity mContext;
    
    private IState mArrayState[] = { 
            new State1(this),
            new State2(this),
            new State3(this)
    };
    
    private enum STATE {
        STATE1(0),
        STATE2(1),
        STATE3(2);
        
        private int type;
        private STATE(int type) { this.type = type; }
        public int toValue() { return type; }
    }

みたいなカンジで interface を実装したクラスの配列と enum を定義しておいて

    private STATE mState;

    public StateTransition(HogeActivity obj) {
        mContext = obj;
        mState = STATE.STATE1;
    }

    protected void kickoff() {
        mArrayState[0].initialize();
    }

コンストラクタと kickoff メソドが上記な形。最初の initialize が、という形ですね。実は今気づいたのですが、これ同様な形で異なる状態遷移があり得ますので、もう少し抽象化して云々な必要があるな。
で、あとは行き戻りな実装が以下な形。

    protected void next() {
        switch (mState) {
        case STATE1:
            mState = STATE.STATE2;
            break;
        case STATE2:
            mState = STATE.STATE3;
            break;
        case STATE3:
            // 終了を通知
            end();
            return;
        }
        int i = mState.toValue();
        mArrayState[i].initialize();
    }
    
    protected void before() {
        switch (mState) {
        case STATE1:
        // no before on STATE1
            break;
        case STATE2:
            mState = STATE.STATE1;
            break;
        case STATE3:
            mState = STATE.STATE2;
            break;
        }
        mArrayState[mState.toValue()].display();
    }

実際の実装はもうちょいアレです。で、IState な interface を実装した例が以下なカンジでしょうか。

public class State1 implements IState {
    private StateTransition mParent;
    
    ButtonClickWaitState(StateTransition obj) {
        mParent = obj;
    }

一応 Context の参照を属性として保持してます。で、interface で定義されてるソレを実装。

    @Override
    public void initialize() {                
        Button btn = (Button)mParent.getContext().findViewById(R.id.buttonenter);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(mParent.getContext(), "enter が押されました", Toast.LENGTH_SHORT).show();
                mParent.next();
            }
            
        });

        btn = (Button)mParent.getContext().findViewById(R.id.buttoncancel);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(mParent.getContext(), "Cancel が押されました", Toast.LENGTH_SHORT).show();
                mParent.before();
            }
            
        });
    }

    @Override
    public void display() {
        initialize();
    }

行き戻りなボタンがあって、という形ですね。

別件のソースを (ry