En-03: 金融実務での Enum 活用
実務でよく登場する Enum の活用パターンを解説します。 DB に保存するコード値の管理、注文ステータスの状態遷移バリデーション、取引種別の分類など、 システム設計に直結する実践的なパターンです。
いつ使うか
- 支払方法・注文ステータスなど、DB に保存する区分値を型安全に扱いたいとき
- 「受付中 → 処理中 → 完了」のような状態遷移のルールをコードで表現したいとき
- 画面表示名と DB 保存コードを一元管理して、定義がバラバラになるのを防ぎたいとき
状態遷移の設計方針
canTransitionTo() を Enum 内に定義することで、 遷移ルールがコードの一箇所にまとまります。 サービス層やコントローラで毎回 if 文を書く必要がなくなり、遷移ルールの変更も Enum を修正するだけで済みます。
サンプルコード
Java 8 では fromCode() の逆引きに for ループを使います。状態遷移の canTransitionTo() に if-else を使うことで、初心者でも読みやすいコードになります。
よくあるミス・注意点
DB コードは String 型の固定値にする
コード値を int やordinal() で代用すると、 Enum の定義順を変更したときに過去データとのマッピングが壊れます。"01"・"PEND" のように 明示的な固定コード値を使いましょう。
fromCode() に存在しないコードを渡すと例外が発生する
DB や API から読み込んだコード値が Enum に存在しない場合、IllegalArgumentException がスローされます。 外部からのデータを受け取る際は try-catch で例外を捕捉するか、 事前に値の検証を行いましょう。
canTransitionTo() の終端状態を必ず false にする
COMPLETED・CANCELLED のような終端ステータスから別のステータスへの遷移を許可してしまうと、 「キャンセルされた注文が再度処理中になる」という不整合が発生します。 終端ステータスは必ず false を返すようにしましょう。
fromCode() のループは要素数が増えると遅くなる
要素数が少なければ問題ありませんが、定数が多い・呼び出し頻度が高い場合はstatic フィールドとしてMap<String, PaymentMethod>をキャッシュしておくと O(1) で参照できます。
テストする観点
fromCode()に各定数のコード値を渡したとき、対応する Enum が返ること(正常系・全件)fromCode()に存在しないコード値(空文字、"99" など)を渡したときIllegalArgumentExceptionがスローされること(異常系)- PENDING から PROCESSING への遷移が true を返すこと
- PENDING から COMPLETED への遷移が false を返すこと(中間ステップを飛ばせない)
- COMPLETED・CANCELLED からの全遷移が false を返すこと(終端状態)
- 各
PaymentMethodのgetCode()・getLabel()が期待どおりの値を返すこと - 境界値: Enum の先頭・末尾定数に対して fromCode() が正常動作すること