LoginSignup
0
0

More than 3 years have passed since last update.

【Java】Enumを使って変更に強いコードを書こう!

Posted at

概要

仕事でコード値の判定が色んなところに散らばってしまった後に、コード値の定義を変更しなければいけなくなった状況が起こりました。
Enumで定義していれば変更箇所はEnum定義だけでよかったなぁ~と思い、自戒の意味を込めて執筆致しました。

状況

  • 「なんちゃら種別」のような種別コード値と名称が複数定義されている
  • その定義の中に、「3:その他」が最後に定義されていた。
  • 新たに追加されることになった種別コードは「3」を使いたい。
  • そのため、「その他」は今後さらにコード値が追加されることを考慮して、 「99:その他」にしたい。

実装

問題のあるコード

SalesOrderMain.java
アプリケーションのエントリーポイント(実行開始メソッド)

SalesOrderMain.java
package main.enum_case;

public class SalesOrderMain {
    public static void main(String...strings) {
        SalesOrder otherOrder = new SalesOrder("販売停止商品", 0, 3);

        // OTHER=3をハードコーディングで判定する場合
        // ⇒ ロジックは通るが、コード値を修正したらif文を修正する必要がある
        if(3 == otherOrder.saleKindCode()) {
            System.out.println("コード値3:販売停止商品です。[ハードコーディング]");
        }

        // OTHERをEnumで判定していた場合
        // ⇒ コードを変更することなく動作する
        if(SalesKind.OTHER.code() == otherOrder.saleKindCode()) {
            System.out.println("コード値" + SalesKind.OTHER.code()+ ":販売停止商品です。[Enum定義]");
        }
    }
}
実行結果
一応ハードコーティングとEnum定義での両方でロジックが通っています。
コード値3:販売停止商品です。[ハードコーディング]
コード値3:販売停止商品です。[Enum定義]
if(3 == otherOrder.saleKindCode())
しかしここがハードコーディングになっているので、コード値の修正に対応していません。

SalesOrder.java
売上種別コードを持つオブジェクト

SalesOrder.java
package main.enum_case;

public class SalesOrder {
    private String _name;
    private Integer _amount;
    private Integer _salesKindCode;

    SalesOrder(String name, Integer amount, Integer salesKindCode){
        _name = name;
        _amount = amount;
        _salesKindCode = salesKindCode;
    }

    public Integer saleKindCode() {
        return _salesKindCode;
    }
}

SalesKind.java
販売種別=3(その他)が定義されている状態

SalesKind.java
package main.enum_case;

public enum SalesKind {
    A(1, "A"),
    B(2, "B"),
    OTHER(3, "OTHER");  

    private Integer _code;
    private String _name;

    private SalesKind(Integer code, String name) {
        _code = code;
        _name = name;
    }

    public Integer code() {
        return _code;
    }

    // Enumで定義されているnameメソッドを重複すため、nameのプロパティはofNameとする。
    public String ofName() {
        return _name;
    }
}

 

Enum定義で解消したコード


SalesOrderMain.java
アプリケーションのエントリーポイント(実行開始メソッド)
SalesOrderのインスタンス生成時の売上種別を99に変更しています。
SalesOrderMain.java
package main.enum_case;

public class SalesOrderMain {
    public static void main(String...strings) {
        SalesOrder otherOrder = new SalesOrder("販売停止商品", 0, 99); // 99に変更

        // OTHER=3をハードコーディングで判定する場合
        // ⇒ ロジックは通るが、コード値を修正したらif文を修正する必要がある
        if(3 == otherOrder.saleKindCode()) {
            System.out.println("コード値3:販売停止商品です。[ハードコーディング]");
        }

        // OTHERをEnumで判定していた場合
        // ⇒ コードを変更することなく動作する
        if(SalesKind.OTHER.code() == otherOrder.saleKindCode()) {
            System.out.println("コード値" + SalesKind.OTHER.code()+ ":販売停止商品です。[Enum定義]");
        }
    }
}
  実行結果 Enum定義で判定していたロジックのみ通っています。
コード値99:販売停止商品です。[Enum定義]
if(3 == otherOrder.saleKindCode())
ここはハードコーディングしていたため、修正しなくてはならなくなりました。

SalesOrder.java
売上種別コードを持つオブジェクト
修正箇所は無いため割愛

SalesKind.java
販売種別=99(その他)に定義し直した状態

SalesKind.java
package main.enum_case;

public enum SalesKind {
    A(1, "A"),
    B(2, "B"),
    C(3, "C"),
//  OTHER(3, "OTHER");  // 元々は3だったが、3が追加されたために99に変更することになった
    OTHER(99, "OTHER");

    private Integer _code;
    private String _name;

    private SalesKind(Integer code, String name) {
        _code = code;
        _name = name;
    }

    public Integer code() {
        return _code;
    }

    // Enumで定義されているnameメソッドを重複すため、nameのプロパティはofNameとする。
    public String ofName() {
        return _name;
    }
}

まとめ

  • コード値の判定ロジックはEnum定義などを利用し、変更に強い構造にしておくこと。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0