社会人のメモ帳

忘れたくないことアレコレ

【名著『リーダブルコード』を解読する】第二章:名前に情報を詰め込む

名前に情報を詰め込む

情報

著者:ダスティン・ボズウェル/トレバー・フォシェ

訳者:角征典

発行:2012年6月22日

書評:リーダブルコード 書評

解読「第2章:名前に情報を詰め込む」

第1章では『読みやすさの基本定理』を理論立ててまとめていた。ブログ主の言葉でまとめた第1章の結論は下記の通り。

  • 自分も含めた開発に関わった者全員が、コードを見た時に、変更すべき箇所が分かり、バグを見つけやすいコードが優れたコードである。

さて、問題は上記に示すような優れたコードを書く具体的な方法である。それについては第2章以降で説明されていくことになり、第2章と第3章では「どういう名前を付けるとより優れているか?」に関してまとめられていく。

第2章においておいて重要な考え方は下記と示されている(章のタイトルと同じだが)。

鍵となる考え

名前に情報を詰め込む。

より具体的には下記の6つの項目が上げられている。

  • 明確な単語を選ぶ
  • 汎用的な名前を避ける(あるいは使う状況を選ぶ)
  • 抽象的な名前よりも具体的な名前を使う
  • 接尾辞や接頭辞を使って情報を追加する
  • 名前の長さを決める
  • 名前のフォーマットで情報を伝える

本著ではそれぞれについて具体例を交えて説明していくのだが、本記事では要点のみをピックアップしてまとめることにする。もっと細かく知りたいという方は本著を読もう。

 

『明確な単語を選ぶ』について。

プログラミングでは、機能ごとに切り分けたメソッドに、それぞれ名前を付けることになる。この名前というのは、当然のことながら、機能に応じた名前を付ける必要に迫られる。

何か情報を取得するメソッドであれば、getという動詞を冠する名前であることが多いのではないだろうか。例えばgetDataというように。しかし、これではあまりに情報が不足し過ぎている。

どこからGetしているのか?

※getを先頭に持ってくるメソッド自体は良くあるし、get~=ダメではないが、他の動詞で言い換えできないかは一旦考慮しても良いと思う。

Dataとはを指すのか?

インターネットからページ情報を取ってくるのであれば、fetchPageとした方が直観的に情報が伝わり、機能が一つに特定できるのだ。

しかし、その際に注意すべきなのは下記に示す鍵となる考えである。

鍵となる考え

気取った言い回しよりも明確で正確な方がいい。

検索する機能を実装したメソッドに対し、「検索する」を意味する英単語だけでfind, search, extract, locate, recover というように多岐に渡る。機能に適した単語を選択する必要があるが、それぞれのメソッドが混合してたくさん存在した場合、それはそれで混乱のもとになる。人によって解釈が分かれるなどということになれば地獄だ。

明確なルール(統一性)と正確さが求められる。

 

『汎用的な名前を避ける』について。

例えばgetDataというメソッドがあったとする。英語を直訳すると、「情報を取る」関数ということになるが、これはどんな情報であれ取ってくるメソッドであれば汎用的に使える名前ということになる。

getDataというメソッドがプログラム全体で10個ある! という地獄を見たくはないだろう。ブログ主は見たくない。

本著ではretValという変数が例として挙げられている。

retreturnの略した形であり、Valvalueの略した形である。つまりretValというのは戻りという意味だ。この戻り値はint型なのかString型なのか、配列なのかそうじゃないのか、そもそも何に使う戻り値なのか……「戻り値という以上の意味がない」のである。

何かのメソッドの戻り値であれば、このretValueという変数名は利用可能である。そのためプログラム全体でretValueが100個ある! という地獄があり得る。可能であればこちらも見たくない。

アドバイス

retValという名前には情報がない。変数の値を表すような名前を使おう。

 

『抽象的な名前よりも具体的な名前を使う』について。

(何度も悪い例として出してしまって申し訳ないが)例えばgetDataというメソッドがあったとする。Dataという単語はあまりに抽象的過ぎる。

このDataが顧客情報(CustomerInfo)のことを指しているのであれば、getCustomerInfoと書くべきだろう。「あぁ。顧客情報を取得するメソッドなんだな」と一目で分かる。

とはいえ顧客情報と言っても、顧客の名称や、顧客の電話番号など、その内訳は複雑であることが予測される。また、顧客は数百人……数千人というように大勢いて、その中の一人を取得しようとしているのかもしれない。条件に合致する顧客情報を取得するメソッドであればfindCustomerInfo、いや……SQLのselect文を使って取ってくるメソッドならselectCustomerInfoとした方が「SQLを使うんだな」と分かってくれるかもしれない。

さて、実際にselectCustomerInfoを使ってみると、戻り値がNULLだった。必ず誰かしらの顧客情報が戻り値として得られるかと思って実装していた場合は、バグの要因となる。しかしSQLのselect文を使っていた場合は、DBのデータ不備や接続失敗などの要因によって失敗することがある。これらもケアする必要があることを、上位クラスに暗黙的に伝えることができる訳だ。

JavaにはOptionalという便利な機能があるので使って欲しい。いずれ別記事で書きたいね。

ここまで書いたのはブログ主の経験によるところが大きい。開発現場や使用しているプログラミング言語、仕様によっても異なるだろう。それぞれに合わせた1個に特定できる具体例というものは変わってくるはずだ。そこは臨機応変に。

 

『接尾辞や接頭辞を使って情報を追加する』について。

メソッド(もしくは変数)に関する重要な要素を示してくれる追加情報が、接尾辞接頭辞になる。

例えばtime_msという変数がある。この変数のms接尾辞にあたり、「単位がmsである」ということを示したいという意図がある。

(よくない例だが)例えばgetDataというメソッドがある。このメソッドのget接頭辞にあたり、「取得するメソッドである」ということを示したいという意図がある。

 

『名前の長さを決める』について。

newNavigationControllerWrappingViewControllerForDataSourceOfClass

上記のような長い名称のclassがあった場合、結局これは何をしたいクラスか読み解くのは至難の業である。これが長すぎるというのは分かってもらえるだろうが、とはいえ適切な長さとはどれくらいかは難しい問題だ。

簡単にルールとして下記の3つがまとめられている。

  1. スコープが小さければ短い名前にする
  2. プロジェクト固有の短縮形は使用を避ける
  3. 不要な単語は使用しない

困った時にテキストエディタごとに用意されている単語補完機能の利用がオススメされている。是非とも自分が使っているテキストエディタの機能を有効活用しよう。

 

『名前のフォーマットで情報を伝える』について。

  1. CamelCase(例:LogReader)
  2. lower_separated(例:log_reader)
  3. kConstantName(例:LOG_READER)

名前のフォーマットとして上記の3つが紹介されている。そして、ぞれぞれの使い分けを明確にすることで、変数かクラスか定数かといった情報を明確化している。大抵の場合、プロジェクトごとにルールを明文化しているはずである。

 

改めてまとめると、下記の6つを意識すれば良いコードに近づく。とりあえず名前を決める際には意識しておこう。

  • 明確な単語を選ぶ
  • 汎用的な名前を避ける(あるいは使う状況を選ぶ)
  • 抽象的な名前よりも具体的な名前を使う
  • 接尾辞や接頭辞を使って情報を追加する
  • 名前の長さを決める
  • 名前のフォーマットで情報を伝える