状態が直交しないならenum、直交するなら他の手段を使おう!

himanoa
·

当たり前な話かもしれない

テーブル設計とかデータ構造について「アカウントが有効かどうか」みたいなのを作る時、booleanでsuspendedみたいなbooleanのフィールドを持つべきか、account_statusみたいなenumを作ってenumエントリーで suspended, active, みたいなのを作るか迷うことがあるだろう。

こういう場合、自分は次の観点でbooleanを選択するか、Enumを使うかを次のようなステップで判断することがおおい

Enumを使う場合の判断例

  1. とりあえずenumで状態を列挙する。

    例えばアカウントの有効状態であったら次の通りだ

    enum { Active = 0, InActive = 1 }

  2. 次のこれらの状態が同時に存在するかを考える。今回の場合はActiveかつInActive、は存在しなさそうなのでenumで良さそうだ

enumを二つに分けたりする場合の判断例

こちらのケースではInActiveの要件がもうちょっと細かい場合を想定してモデリングしてみる。

有効、運営にサスペンドされて無効、ユーザー自分でサスペンドして無効の3つが存在するみたいな感じだ

  1. enumで状態を列挙してみる

    enum { Active = 0, SuspendedByUser = 1, SuspendedByBackyard = 2 }

  2. enumエントリー内に同じような内容が二つあるので状態が直交していそうだ。

  3. 直交しているものをEnumで扱うとEnumエントリーが組み合わせ爆発して大変そうなので、直交していない部分を別にしよう

    enum AccountStatus { Active = 0, Suspended = 1 }

    enum SuspendedReason { ByBackyard =0, ByUser = 1}

booleanを使う場合

永続化された条件をプログラムで論理結合したい場合はbooleanが適当な構造の場合がおおいかもしれない。

例えばアクセス権限みたいなのは、一つの操作で二つ以上のリソースにアクセスする必要があって、二つのリソースへのアクセス権限を持っている必要がある みたいなやつ

こういうのはフィールドの主な使用用途が合成前提なのでbooleanだったりbooleanの配列として表現すると嬉しいことがおおい、みたいな。

さいごに

みんなどうやって判断してるかおしえてね^^