読者です 読者をやめる 読者になる 読者になる

kojiko-android’s blog

開発中にハマった時の解決策や、忘れがちなことを残しておきます。

【電卓アプリを作るvol.3】ソースコード1/2

前回まで・・・
電卓のアルゴリズムについて考えました
今回は、ソースコードを掲載します。
参考書のような詳細な解説は割愛しますが、
状態遷移表とコードを何度も見比べれば、
理解できると思います。

アンドロイドスタジオのエクスプローラービューは↓こうなってます
f:id:kentaro198477:20160919225501p:plain

Context

各状態クラスから、Calc(電卓のメインの処理)クラスに知らせるためのインターフェイス

public interface Context {

    void addNum(int key);
    void setLeftDouble();
    void setEnzanshi(int key);
    void changeState(State instance);
    void clear();
    void backSpace();
    void percent();
    void dispZero();
    void keisan();
    void allClear();
    void teisuKeisan();
    void setRightValue();
    void dividedBy100();
}
State

各状態クラスに継承させるインターフェイス

public interface State {

    static final int STATE_A = 1,STATE_B = 2,STATE_C = 3,STATE_D = 4;

    int getStateValue(Context context);
    void inputNumber(Context context, int key);
    void inputEnzanshi(Context context, int key);
    void inputClear(Context context);
    void inputEqual(Context context);
    void inputBackSpace(Context context);
    void inputPercent(Context context);
}
StateA

左辺入力中の状態
以下、各ステートは複数のインスタンスは必要ないので、
シングルトンパターンを採用しています。
シングルトンについては、詳しく解説されたサイトが多数あるので
そちらをご参考ください。

public class StateA implements State{
    private static StateA ourInstance = new StateA();

    public static StateA getInstance() {
        return ourInstance;
    }

    private StateA() {
    }
    
    @Override
    public int getStateValue(Context context) {
        return STATE_A;
    }

    @Override
    public void inputNumber(Context context, int key) {
        context.addNum(key);
    }

    @Override
    public void inputEnzanshi(Context context, int key) {
        context.setLeftDouble();
        context.setEnzanshi(key);
        context.changeState(StateB.getInstance());
    }

    @Override
    public void inputClear(Context context) {
        context.clear();
    }

    @Override
    public void inputEqual(Context context) {

    }

    @Override
    public void inputBackSpace(Context context) {
        context.backSpace();
    }

    @Override
    public void inputPercent(Context context) {
        context.dividedBy100();
    }
}
StateB

演算子入力中の状態(抽象メソッド以外は省略)

    @Override
    public int getStateValue(Context context) {
        return STATE_B;
    }

    @Override
    public void inputNumber(Context context, int key) {
        context.dispZero();
        context.addNum(key);
        context.changeState(StateC.getInstance());
    }

    @Override
    public void inputEnzanshi(Context context, int key) {
        context.setEnzanshi(key);
    }

    @Override
    public void inputClear(Context context) {
        context.clear();
        context.changeState(StateC.getInstance());
    }

    @Override
    public void inputEqual(Context context) {
        context.setRightValue();
        context.keisan();
        context.changeState(StateD.getInstance());
    }

    @Override
    public void inputBackSpace(Context context) {

    }

    @Override
    public void inputPercent(Context context) {
        context.percent();
    }
StateC

右辺入力中の状態(抽象メソッド以外は省略)

   @Override
    public int getStateValue(Context context) {
        return STATE_C;
    }

    @Override
    public void inputNumber(Context context, int key) {
        context.addNum(key);
    }

    @Override
    public void inputEnzanshi(Context context, int key) {
        context.setEnzanshi(key);
        context.keisan();
        context.setLeftDouble();
        context.setRightValue();
        context.changeState(StateB.getInstance());
    }

    @Override
    public void inputClear(Context context) {
        context.clear();
    }

    @Override
    public void inputEqual(Context context) {
        context.setRightValue();
        context.keisan();
        context.changeState(StateD.getInstance());
    }

    @Override
    public void inputBackSpace(Context context) {
        context.backSpace();
    }

    @Override
    public void inputPercent(Context context) {
        context.percent();
    }
StateD

イコールが押された直後の状態(抽象メソッド以外は省略)

 @Override
    public void inputNumber(Context context, int key) {
        context.allClear();
        context.addNum(key);
        context.changeState(StateA.getInstance());
    }

    @Override
    public void inputEnzanshi(Context context, int key) {
        context.setLeftDouble();
        context.setEnzanshi(key);
        context.changeState(StateB.getInstance());
    }

    @Override
    public void inputClear(Context context) {
        context.clear();
    }

    @Override
    public void inputEqual(Context context) {
        context.teisuKeisan();
    }

    @Override
    public void inputBackSpace(Context context) {

    }

    @Override
    public void inputPercent(Context context) {
        context.dividedBy100();

    }