Ch.1~2(理解しやすいコード&名前に情報を詰め込む)|『リーダブルコード』読解メモ #1

f:id:lib-arts:20191013194556p:plain

Pythonのプログラミングについてのシリーズを書いているのですが、Pythonそのものについては#10をもって終了したので、もう少し広い視点でのコーディングについてもまとめておければと思い『リーダブルコード』を課題本に設定しまとめていきます。

O'Reilly Japan - リーダブルコード

平易に書かれており、軽く読み流して何度か振り返るのが良さそうなので、重要なポイントだけ抜粋してまとめていく形式を取れればと思います。#1ではCh.1の『理解しやすいコード』とCh.2の『名前に情報を詰め込む』について確認していきます。(基本的に本を片手にご確認いただく前提なので、細かいところの記述は省略すると思います。勝手に解釈した上での要約なので、万が一解釈違いは生じていたとしたらご容赦ください。)
以下目次になります。
1. 理解しやすいコード
2. 名前に情報を詰め込む
2-1. 明確な単語を選ぶ
2-2. tmpやretvalなどの汎用的な名前を避ける
2-3. 抽象的な名前よりも具体的な名前を使う
2-4. 名前に情報を付加する
2-5. 名前の長さを決める
2-6. 名前のフォーマットで情報を伝える
3. まとめ


1. 理解しやすいコード(簡単な要約)
執筆にあたって5年間ほど集めた「ひどいコード」がなぜひどいのかを分析してみたところ、全ての原則は「コードは理解しやすくなければならない」という原則に行き着いた。
1行2行に詰め込んで書くのとifやelseなどを用いて丁寧に書き下すだと、詰め込んで書く方が簡潔だが、ある程度書き下している方が安心できる。この際にどちらにするかを選ぶにあたっては「コードは他の人がなるべく早く理解できるように書かなければいけない」というのを意識すると良い。ここで「理解する」には高いハードルを設けてあり、変更を加えたりバグを見つけたりできるという意味を内包している。
「読みやすさ」や「理解」にフォーカスをあてることは効率化や設計、テストなどとの条件とも競合しないのでなるべく取り組んでみると良い。常に「このコードは理解しやすいだろうか?」を自問するようにすると良い。

 

2. 名前に情報を詰め込む(簡単な要約)
Ch.2では「名前に情報を詰め込む」にあたっての様々な考え方がまとめる。いい名前をつけることで低コストで多くの情報を伝えることができる。したがってCh.2では情報を詰め込んだ名前のつけ方を紹介していく。


2-1. 明確な単語を選ぶ
「名前に情報を詰め込む」には、明確な単語を選ばなければならない。例えば「get」はどこから取得するかがわからないなど、あまり明確な単語ではない。また、Size()も高さなのかメモリの大きさなのかがわかりにくく、明確な単語ではない。目的に適した名前をつけるにあたっては、Height()やNumNodes()やMemoryBytes()などの方がわかりやすい。
また、Stop()も明確ではなく、取り消し不可にするならKill()を使うと良いし、一時的に止めるだけならPause()にしても良いかもしれない。同様な例として下記にまとめる。

find -> search、extract、locate、recover
start -> launch、create、begin、open

気取った言い回しではなく、上記のような明確で正確な名前をつけられると良い。


2-2. tmpやretvalなどの汎用的な名前を避ける
tmp・retval・fooのような名前をつけるのは「名前のことなど考えていません」と言っているようなものなので注意が必要である。このような「空虚な名前」をつけるのではなく、エンティティの値や目的を表した名前を選ぶようにする方が良い。
いい名前というのは変数の目的や値を表すものである。例えば2乗の合計を行う関数であれば返り値としてretvalではなく、sum_squaresなどを用いる方が良い。
また、下記ではtmpとループイテレータについてそれぞれ工夫点をまとめる。

・tmpは二つの変数を入れ替えるなど一時的な保管が必要な変数にのみ使うとよい。
・ループイテレータはインデックスが複数ある際にi、j、kだと見づらいので、クラブのユーザーを調べるなどのケースではclub_i、members_i、users_iなどにすると見やすくて良い。

 

2-3. 抽象的な名前よりも具体的な名前を使う
変数や関数などの構成要素の名前は抽象的でなく、具体的なものにすると良い。
例えば任意のTCP/IPポートをサーバがリッスンできるかを確認するメソッドにServerCanStart()を用いるよりCanListenOnPort()を用いた方が具体的でわかりやすい。


2-4. 名前に情報を付加する
名前に情報を付加するにあたって、具体的な適用シーンを下記にまとめる。

・時間やバイト数のように計測できるものであれば、変数に単位を入れておくと良い。
-> 例えばページの読み込みの計測などで単位としてミリ秒を用いる際はstart_msやelapsed_msなどを用いると良い。

・危険や注意を喚起する情報も追加した方が良い。
-> セキュリティ問題の多くは、プログラムの受診するデータが安全ではないことが原因で発生しているので、このようなデータにはuntrustedUrlやunsafeMessageBodyなどの変数名を使うと良い。逆にデータを安全にする処理を行なった後はtrustedUrlやsageMessageBodyにすると良い。

 

2-5. 名前の長さを決める
いい名前を選ぶときには「長い名前を避ける」という暗黙的な制約がある。長くなりそうな時はevaluationの代わりにeval、documentの代わりにdoc、stringの代わりにstrを用いるなどや、一般的な略し方であれば頭文字で略したりする。またConvertToString()をToString()にしても意味が通じる場合はそうするケースもある。


2-6. 名前のフォーマットで情報を伝える
CamelCase、lower_separatedなどの記法を意味ごとに統一することで名前のフォーマットでも情報を伝えることができる。


3. まとめ
#1ではCh.1の『理解しやすいコード』とCh.2の『名前に情報を詰め込む』について取り扱いました。実践している点もありますが、抜けていた点の参考にもなるなど時折見直す方が良い内容だと思いました。
#2ではCh.3の『誤解されない名前』とCh.4の『美しさ』についてまとめていきます。