id key name type code label text を適切に使い分ける

## はじめに

ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています @misuken です。

今回はWebフロントに限らず、幅広く利用可能な単語の使い分けに関するノウハウを紹介します。

## 意外と曖昧な単語の使い分け

どんなシステムであっても id key name type code label text の中のいずれかの単語が含まれていると思いますが、それらの使い分けはしっかりできているでしょうか？

それらの使い分けが適切にできていないと、システムのある部分ではこういう意味、ある部分ではまた別の意味となってしまい、広範囲のコードや都度定義を見にいかないと正しい意味の理解できないシステムになってしまいます。

人によって使い方が違ったり、チームである程度の方針が決まってない場合も、それが大規模になったときに複雑さが増す原因になったりします。

## 単語ごとの用途

これらの単語は、単語単体、または末尾に来る単語です。
その単語を見たとき、その定数や変数がどういう意味かがはっきりわかればシステム全体から曖昧さが無くなり、複雑さを減らすだけでなく、設計が楽になったりレビューも楽になるなど、様々な恩恵を得られます。

| 名前 | 識別子 | 型候補 | 用途 |
|---|---|---|---|
| id  | ◯ | number &#x7C; string | 一意な識別子 |
| key | ◯ | number &#x7C; string | Reactの要素識別子、オブジェクトやMapの識別子 |
| name | △ | string | 非一意な識別子 一意な識別子 名称 |
| type | ◯ | string | 種類 型 |
| code | ◯ | number &#x7C; string | 符号 文字コード ステータスコード エラーコード |
| label |  ✕ | string | 表示に使用される名称 |
| text |  ✕ | string | 表示に使用される文字列 |

### id

一意な識別子として意味のあるものだけにidを使用します。

### key

Reactの場合は同階層の要素同士の識別子に使用します。
一般的にはkey/valueの関係に該当するようなオブジェクトやMapで識別子として使用します。

つまり、フラットなスコープにおいて適した識別子と言えます。

### name

HTMLの場合はform要素のname属性など、文書内で非一意な識別子として使用します。
ラジオグループやチェックボックスでは複数の要素に同じ文字列を指定することで、それらがグループとして認識されます。

何らかのサービスを利用するユーザーの名前として使用する場合は名称(labelに近い)でありつつ、非一意な識別子(例えば "太郎" が複数いるなど)でもあります。あだ名に該当する場合はnicknameを使ったほうが明確で、姓名の場合はfullNameにするなど、単純なnameをなるべく避けるほうがコードから意図を読み取りやすくなります。

TwitterのscreenNameのように一意な識別子として使用される場合もあります。

nameは用途の範囲が広い単語なので、より慎重に扱うようにすると良いでしょう。

### type

種類や型を表すような文字列に使用します。

typeと同じでも、より明確な意図であるrole(役割)、category(分類)などが適している場合はそちらを使用します。
roleはHTMLの分野では文字列ですが、権限周りの分野ではオブジェクトになる場合もあるので、分野ごとに単語に紐づく型が変わることもあります。

### code

意味を識別する目的などに使用します。

文字を表現するための文字コード、HTTPの通信結果を伝えるためのステータスコード、エラーの種類を特定するためのエラーコードなど。

何も考えずにtypeを使っている場合でも、codeのほうが適している場面は多々あります。

### label

空白や記号等なんでも含まれるような文字列に使用します。
曖昧さが含まれるため、識別子としては利用すべきではありません。

人間が識別するための名称(ラベリング)的な役割の物に使用します。
長い文字列や文には該当しません。

### text

空白や記号等なんでも含まれるような文字列に使用します。
曖昧さが含まれるため、識別子としては利用すべきではありません。

長い文字列や文にも使用できます。

## その他の識別子

その他の識別子でも特徴を抑え、適用方針を決めておくと便利なものがあります。

| 名前 | 識別子 | 型候補 | 用途 |
|---|---|---|---|
| title | △ | string | 題名 |
| category | ◯ | (string) | 大きな分類 |
| genre | ◯ | (string) | カテゴリ内の詳細な分類 |

### title

役割はnameと似ていますが、より用途が限定されたnameのような存在です。
HTMLの分野ではtitle属性と名前が競合して相性が悪いので、競合する場合はtitle属性に使用する文字列をtitleTipTextなどと明確化すると良いでしょう。

### category や genre

これらはcategoryIdやgenreIdなどとしたほうが良い場合が多々あります。
categoryという名前で`string`型の場合、それが識別子の "game" なのか、ラベルの "ゲーム" なのか判断が付かないためです。

もしcategoryIdとcategoryLabelのような名前になっていれば誰でも明確に判断できるでしょう。

このように`string`という同じ型の中でも分類が存在しており、それらを正確に見極めて設計することで、システム全体の統一感や理解の容易性が格段に変わってきます。

### status や error

これらもcategoryとgenreと同様です。
statusCodeやerrorCodeなどとしたほうが良い場合が多々あります。
errorという名前で`string`型の場合、それがエラーの理由を識別するための "required"(必須) なのか、エラー文の "入力は必須です" なのか判断が付かないことがあるからです。

もしerrorCodeとerrorText or errorMessageのような名前になっていれば誰でも明確に判断できるでしょう。

## ドメインとの関係性

単語の分類で重要なドメインとの関係性を考える上では、[BCD Design](https://qiita.com/misuken/items/19f9f603ab165e228fe1)を一読することをおすすめします。

今回の記事はコンポーネントとは関係ないのですが、id〜textとtitleはプリミティブ、category genre status errorは関心のように、単語の分類に特化したBCD Designの概念をそのまま利用できる面があるからです。

BCD Designの分類であれば、category genre status errorはcommon(共通の関心)に該当するものになります。

そのため、コンポーネントと同様にcategoryId genreId statusCode errorCodeのように単語の組み合わせが **関心+プリミティブ(型)** のようになったとき、情報量と名前のバランスが安定すると考えられます。

## まとめ

主に文字列で表現される各単語の使い分けはいかがだったでしょうか？
今まで何となく使用していて、システムの中でブレや競合が生じてわかりにくくなっている部分に心当たりがある方もいらっしゃると思います。

個人的には、複雑なシステムをキレイに設計出来ている人ほど、こういった細部の単語の使い分けを意識し、統一感のあるシステムを構築している傾向があると思っています。

設計する分野によっても多少型が変わってくることはありますが、その領域ごとに常に同じ意味には同じ単語を割り当てていくことは非常に重要です。

名前に悩んでいた方もこの記事を参考にステップアップしてみてはいかがでしょうか？