命名力を高める

この記事はand factory Advent Calendar 2018 Day 19の記事になります。
前日は@haguhoms(a.k.a はぐっ) の「[アニメーションとお近づき ~すのうふれいくを君と 第ゼロ章~](https://qiita.com/haguhoms/items/c58512a51ee04eb79d98)」でした。


命名、大事ですよね。リーダブルコードでも命名に関して非常に多くのページを取っていますし、何より日頃の業務で命名が微妙なために、誤解やバグを生んでしまったという経験は多かれ少なかれあるかと思います。

弊社でも様々なプロジェクトを進めてきた上で、少しづつチーム開発において命名の精度を高める事が出来てきたように思います。今日はそんな命名の精度を上げる、つまり命名力を高める方法をシェアします。

# 全般
## 用語一覧を早めに作って読み合わせる
仕様書が一通り出揃った状態で用語一覧を先に作ってしまいます。そしてそれを関連する全員で読み合わせるとベースとなる文言や命名のルールが統一されます。
作るときに合わせてスネークケースとキャメルケースと両方作っておくと便利です。

<img width="461" alt="Screen Shot 2018-12-18 at 23.00.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/145904/fe3d67fe-a3c6-21b0-f1e8-51e0a144e3d6.png">


上記のようにスプレッドシートを作成します。入力するのは論理名とスネークケースだけで、アッパーキャメルとロワーキャメルは以下のようにしておけば自動作成されます。

```
//アッパーキャメル
=SUBSTITUTE(PROPER(B2),"_","")
//ロワーキャメル
=LOWER(LEFT(B2,1))&MID(SUBSTITUTE(PROPER(B2),"_",""),2,LEN(B2))
```

ときにはチームでの意見の対立が発生します。最近では金庫をSafeにするか、VaultにするかKinko（実際には〜金庫と固有名詞だったのでKinkoも候補に上がりました）にするかで意見が分かれました。

こういう時はSlackとかで軽くアンケートをつくってチームの反応を見ると決めやすいです。僅差でSafeになりましたが、プロジェクトによってはVaultやKinkoになっていたかと思います。

そうやって、納得感があるものを早めに作っておくと楽になります。

## 英語の品詞に気をつける
プログラムは英語ではないのですが、アルファベットと英単語を使っているので英語のように考えるとより自然でわかりやすく良い命名になるかと思います。英語圏の人が書いたソースも多いでしょうし。

ほとんど以下の記事でいいたい事が書かれていますので、是非一読をお勧めします。
[モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう
](https://qiita.com/jnchito/items/459d58ba652bf4763820)

実際に以下のようにレビューで指摘したりしています。

```
//財布に購入コインとボーナスコインがあるとして
Wallet.buyCoin -> Wallet.purchasedCoin

//xxxというシステムに接続しているか、していないかのbool値
User.is_xxx_connection -> User.is_xxx_connected, User.has_xxx_connection

//店がクローズしているか
Shop.isClose -> Shop.isClosed
```

付け足すとすれば、もし英語で説明でしようとして脳内で会話をシュミレートすると、それなりに正しいものができるんじゃないかと思っています。

一番目の例なら、

```
What is this coin ?
This coin is purchased coin, It is user purchased.
On the other hand, user have bonus coin. That is user get on bonus.
```

二番目の例なら、

```
This user is connected to xxx system ?
Yes, this user connected to xxx system. The user has connection to xxx system.
```

三番目の例なら、

```
What is this shop's status ?
This shop will open at 10 am. It's 9 am now. So the shop is closed.
```

みたいな脳内会話をして、自然だと思える会話から切り取って命名を決めてます。

ここで大事なのは英語として正しいかというよりかは伝わるか、腑に落ちるかです。そういう意味で日本語を残すこともありますし、難しい単語を避ける事もあります。逆に単語自体は正しそうでも品詞が間違っていると伝わらないか、伝わったとしてもわかりづらく引っかかるので直します。

もちろん自分の感覚が間違っているケースもあります。何か新しいものを作る関数でnewXxxという関数がレビューで上がったきたのですがnewって動詞じゃないし、この関数名微妙じゃないという指摘をあげたのですが、Goの公式の関数で（英語圏の方が書かれたもので）newXxxという関数が存在していて、まあありなのかという結論に至りました。他の方のソースを読む事、英語のみで言えばできる人やネイティブにフィードバックをもらうという事が必要かつ大事かと思います。

ここは各々が精進していきましょう。

# サーバサイドに関する事
現在自社では開発にGoを使っており、その上で行なっているアプローチを説明します。

## protocol bufferを使う
protocol bufferを使う、自社だとgoなのでgrpcを使っているのですが、これには非常に良い事があって、それはドキュメントなのでレビューをしやすいという事です。

従来API設計書としてexcelやswaggerを使っていたのですが、レビュー間違いを見つける、そしてそれをわかりやすく伝えるって結構大変です。どうやっても漏れは発生するので、以下に発見しやすいようにみる場所を減らし、わかりやすく指摘できるように仕組みを整えることが大事です。

その点テキストにしておけば見やすいし、ソース管理しやすくプルリクでのレビューもしやすいです。かつ同じものをサーバのエンジニアもアプリのエンジニアも見るのでより間違いが減ります。

一時期はswaggerに大変お世話になっているのですが、現状はprotoがいいなと思っています。

## スペルチェックの静的解析ツールを使う
機械的に解析して見つけるのも、良いアプローチかと思います。
以下、スペルミスをチェックして検知してくれるGoのツールです。
https://github.com/client9/misspell

これをCIで必ずプルリク時にチェックしています。完全ではありませんが存在しない単語や複数形のミス等は弾けています。

# まとめ
以上、命名力を高めるには以下のように技量面と仕組面の両方で考えていくと良いのではと思います。

 - 個人+チームの技量を高める
   + 英語の品詞を考える
   + 英語力を高める
   + 一般的なケースを学ぶ、ソースを読む
 - 仕組みを整える
   + 用語一覧の作成とチーム共有
   + protoの活用とレビュー
   + 静的解析ツールとCI

命名力を高めていきましょう！