Java
Android
リファクタリング

[読書メモ]リファクタリング - タイプコードの置き換え(振る舞いに影響を与えるタイプコードの場合)- 2

What? Stateパターンとは?

https://qiita.com/takutotacos/items/654e204d618d2059de7f
要はこれと似たことをやるためにあります。

↑をやりたいけど、タイプコードがオブジェクトの生存期間中に変化する時にこのパターンを使用します。
タイプコードの変更にも対応できる サブクラス化です。

How? どうやるか?

変更前.java
class Employee {
    static final int ENGINEER = 0;
    static final int SALESMAN = 1;
    static final int MANAGER = 2;

    private int type;

    public Employee(int type) {
        this.type = type;
    }

    int payAmount() {
        switch (type) {
            case ENGINEER: return monthlySalary;
            case SALESMAN: return monthlySalary + commission;
            case MANAGER : return monthlySalary + bonus;

        }
    }
}

上記のswitch文を取り除きたいです。そのために、以下のような実装を行います。

変更後.java
class Employee {
    private EmployeeType type;

    int getType() {
        return type.getType();
    }

    void setType(int type) {
        this.type = EmployeeType.newType(type);
    }
}

abstract class EmployeeType {
    public static final int ENGINEER = 0;
    public static final int SALESMAN = 1;
    public static final int MANAGER = 2;

    static EmployeeType newType(int code) {
        switch (code) {
            case EmployeeType.ENGINEER: return new Engineer();
            case EmployeeType.SALESMAN: return new Salesman();
            case EmployeeType.MANAGER : return new Manager();
            default: throw new IllegalArgumentException("不正な従業員コード");
        }
    }

    abstract int getType();
}

public class Engineer extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.ENGINEER;
    }
}

class Salesman extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.SALESMAN;
    }
}

class Manager extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.MANAGER;
    }
}

この後に、給料計算ロジックをそれぞれのサブクラスに実装すればクライアントクラスからはオブジェクト生成以外では条件分岐がなくなりました。
これなら、サブクラスの種類を増やしてもロジックの実装を忘れることがなくなりそうですね。
オブジェクト生成時に、switch文にサブクラスを追加し忘れてもエラーを吐いて終了してくれるので実装忘れを認識しやすいというデバッグのしやすいプログラムになりました。