概要
仕事でコード値の判定が色んなところに散らばってしまった後に、コード値の定義を変更しなければいけなくなった状況が起こりました。
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定義などを利用し、変更に強い構造にしておくこと。