概要
仕事でコード値の判定が色んなところに散らばってしまった後に、コード値の定義を変更しなければいけなくなった状況が起こりました。
Enumで定義していれば変更箇所はEnum定義だけでよかったなぁ~と思い、自戒の意味を込めて執筆致しました。
状況
- 「なんちゃら種別」のような種別コード値と名称が複数定義されている
- その定義の中に、「3:その他」が最後に定義されていた。
- 新たに追加されることになった種別コードは「3」を使いたい。
- そのため、「その他」は今後さらにコード値が追加されることを考慮して、
「99:その他」にしたい。
実装
問題のあるコード
SalesOrderMain.java
アプリケーションのエントリーポイント(実行開始メソッド)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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定義での両方でロジックが通っています。
12 コード値3:販売停止商品です。[ハードコーディング]コード値3:販売停止商品です。[Enum定義]
if(3 == otherOrder.saleKindCode())
しかしここがハードコーディングになっているので、コード値の修正に対応していません。
SalesOrder.java
売上種別コードを持つオブジェクト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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(その他)が定義されている状態
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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に変更しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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定義で判定していたロジックのみ通っています。
1 コード値99:販売停止商品です。[Enum定義]
if(3 == otherOrder.saleKindCode())
ここはハードコーディングしていたため、修正しなくてはならなくなりました。
SalesOrder.java
売上種別コードを持つオブジェクト
修正箇所は無いため割愛
SalesKind.java
販売種別=99(その他)に定義し直した状態
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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定義などを利用し、変更に強い構造にしておくこと。
コメント