プログラミングで名前つけるときに注意すべきこと(WEB+DB VOL.110)

# これはなに？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1758960/cdece862-ca1b-4115-d701-24b5165f5797.png)

最近、業務でコードを書いてる時に変数名/モジュールの名前の指摘を受けることが多かったので、[WEB+DB VOL.110](https://gihyo.jp/magazine/wdpress/archive/2019/vol110)の「名前付け大全」特集を読んで、もっとスッキリとしたネーミングができるように勉強したので、その内容についてまとめてます。

# 「良い名前」とは何か
- 名前が重要なのはなぜ？
    - 理解しやすく/変更に強く/読みやすいコードを書くために大事
    - 名前と内容が不一致だと
        - コードを書くときに毎回思考にリソースを割かないといけなくなる(不毛)
        - 挙動が予測できない(`save`という名前入ってるのに削除されたり)
        - あとで変更するのも大変

# 名前付けの理論
- どんな名前なら良いの？
    - 書籍[CODE COMPLETE](https://www.amazon.co.jp/Code-Complete-Developer-Practices-English-ebook/dp/B00JDMPOSY/ref=sr_1_5?crid=2242U3RXUPZS4&keywords=code+complete&qid=1644237807&s=books&sprefix=code+com%2Cstripbooks%2C165&sr=1-5)
        - 変数が表現するものを正確/完全に言い表す
    - 要素は二つ
        - 適切な名前(+シンプルさ)
        - 正しく書かれたもの

## 適切な名前
- `名前から想像されている意味`と`システム上の挙動`が一致している
- シンプルであること(`article_data`よりも`article`だけで十分)
- 例. saveRecord (レコードを保存するメソッド)
    - save：何らかのものを保存
    - Record：データ列、レコード
- 不一致の三大パターン
    - 名前と挙動のずれ
        - 例. `latest_articles`という変数を定義するときに、DB上の操作では3日前のarticleを取ってくるようにしている。`latest`という単語には「三日前」という意味が含まれていない(`articles_created_in_three_days`とかにすべき)
    - 名前の意味が狭すぎる
        - 例. データを保存する`saveRecord`メソッドの最後にキャッシュの削除まで行われている(名前から削除まで類推することは困難)
    - 名前の意味が広すぎる
        - 例①. `getPage`という「インターネットページを取得する」関数は、名前だけだとDBやファイルシステムなど、どこからページを取ってきているのか分からない
        - 例②. 下書き状態と公開状態を分けるだけで良いのに、stringなDBカラムを用意してしまう(booleanでいいよね？)

## 正しく書かれた名前
- 要素
    - 英語としての正しさ
        - 語彙
        - 文法
        - スペル
    - 文体の統一
        - キャメルケース(HogeHoge)
        - スネークケース(hoge_hoge)
        - ケバブケース(hoge-hoge)

## 名前付けの実践
- パターン①：挙動とのずれ
    - スペルを間違えて別の意味になる
    - 思いついた単語と意味がずれてる
        - 語彙力を過信せず辞書で調べよう
- パターン②：狭い名前
    - if文などの例外処理をメソッド名に含めていない
        - 変数名はもれなくダブりないようにつけよう
- パターン③：広い名前
    - 安易な(意味が曖昧の)単語を選ぶ
        - info, dataなどはより明確な意味になるように努力する
        - checkは挙動が分かりにくい(true, falseなども明確でない)ので特に注意する
    - 重要な単語を不用意に使ってしまう
        - user, operationなどの名前は多用しないようにする
        - 使うにしても「何を」を狭める単語を使う
    - 実装の変更によって意味が変わる
        - テストなどで動作の変更を理解できるようにする
- パターン④：シンプル
    - 助長な名前をつける
        - 明確に表現できる単語などがあるならそっちを使う
   - 情報量のない名前をつける
        - 無駄な単語は省く

# 英語の壁の克服
- 4つのstep
    - 品詞
    - 時制・法・法助動詞
    - 語彙
    - スペリング

## 品詞
- 自分が表したいものが`名詞`なのか`動詞`なのか考えてみる
- 名詞系
    - 「なにであるのか」を指し示す時に使う
    - 一言で表せないなら修飾語を検討する
- 動詞系
    - ルーチン(一連の動作をまとめた塊)を表す時に使う
    - 動詞と目的語の順番に気をつける(x`EmailSend`, o`SendEmail`)
    - 値を返すルーチンは名詞系か否か(以下の場合は動詞のほうがよい)
        - ルーチンでないものと混同されやすい
        - 処理の重さをエンジニアに認識してもらう

## 時制・法・法助動詞
### 時制
- よく使うもの
    - 単純系過去・現在・未来(did, do, will do)
    - 進行形現在(be doing)
    - 完了形現在(done)
- ポイント
    - 前後で挟むような変数を作成するときは`before`, `after`とかを使った方が対の関係を表現しやすい
    - `has`は動詞と勘違いされることがあるので、`did`などを使うといい

### 法助動詞
- よく使うもの
    - can
    - should
    - must
- ポイント
    - canの使い分け
        - can：能力
        - allow：許可
        - could：可能性
    - 「必要性」の使い分け
        - 動詞に対して使う：should
        - 名詞に対して使う：need
## 語彙
- いい感じの命名を見つけた後は...
    - 日本語の直訳だけでなく、英単語のイメージをとらえてみる(Google画像検索とかで)
    - 対で使う言葉が適切であるか確かめる(next↔︎previous, not "before")
    - コンピュータ分野特有の反対語
        - get↔︎set
        - deep↔︎shallow
        - allocate↔︎deallocate
        - enqueue↔︎dequeue
        - head↔︎tail
        - expand↔︎collapse
        - inflate↔︎deflate
    - 2語で構成された単語を1語で表現できないか検討する(無理に難読単語を使う必要はなし)
        - openLock↔︎unlock
    - ドメインで使われている言葉も調べてみる
## スペリング
- 簡単な単語の方がミスりやすいから気をつけましょう

## さらなる工夫
- 単数系/複数形が似ているものは名前の差分を大きくする
    - 単数：saveItem, 複数：saveAllItems
- 省略形は本当に省略する必要があるか考える
- 同音異義語の被りがないようにする(思考するときや、相談するときに間違いやすいので)
- 品詞が違っても綴りが同じものは誤解されないか先に検討しておく
    - save, match, free, clean

# さらなる効率化の手法
- 語彙の探索手段
    - 英英辞書、英和辞書、和英辞書(macOSであれば全部入っている)
    - 既に存在しているコード
    - [schema.org](https://schema.org/)(インターネット上の共通用語集)
    - 自分が書こうとしているドメインと近いOSSのコード