Enumの値を定義する場合、自然数の連番(1, 2, 3, …)で定義することが多いのではなかろうか。言語によっては値を定義しない場合に勝手にこの値が割り当てられる。この値を1, 2, 4, 8といったようにビットシフトを行った値で定義するメリット、デメリットを考える。
一番のメリットは値を複数持つことに仕様が変更になった場合に変更箇所が少ないことだろう。例えばデータベースにint型で値を格納していた場合、複数の値を定義するにはレコードを複数持つようにする等の変更が発生する。例えばレコードを複数持つように変更した場合、レコードが1件しか返ってこない前提で書いている箇所もあるだろう。また、テーブルのキーも変更しないといけないかもしれない。キー変更によって、さらに予期しないところで変更が発生する、という状況になりがちだ。対して1, 2, 4, と定義した場合、DBのスキーマを変更する必要はない。これはプログラムアップデート時の負荷がかなり下がる。また、1行で取得できていた箇所はそのまま1行で取得される。
デメリットとしては、ビットマスクによって判定しなければなくなる点だろう。変更前は同じ値かどうかで判定すればよかった箇所がビットマスクの演算に置き換える必要が出てくる。また、テーブルの1つの列に複数の情報が詰め込まれる問題も出てくる。
一般的にテーブルの1つの列に複数の情報を含めることは良しとされていない(アンチパターンとして、文字列をカンマで連結して格納する、というような場合が挙げられる)ので、やはりレコードは複数行になるようにテーブル設計を変更する方が、後から困らない設計に思える。
今回はDBに値を格納することを中心に考えたが、現時点でDBを使っていないような場合でも今後DBに値を格納することが発生する可能性は十分あると思う。そうなった場合にEnumが1, 2, 4, と定義されていたら1つの列として定義してしまうのではないだろうか。そのようなアンチパターンを誘発させるようなことにならないように、最初から自然数(1, 2, 3, …)で定義しておくのが良いように思える。
コメント