2年目、3年目と時が経つにつれて、他人が書いたコード見てコメントをする機会は増えていく。
このときに(主にコーディングに関する)自分の考え方を言語化して他人に伝える、というのはとても骨が折れる作業だ。
そこで、これまでに他人にしてきたコメントを思い返しつつ「普段どんなことを考えながらコーディングしているか」「プルリクを見るときにどんなところを見ているか」という観点を整理してみた。
もちろんただ文字に起こしただけでは伝わらない。 何度も繰り返し改善案のコードとセットにして伝える、という積み重ねの先に観点・感覚が身につくはずだと信じている。
※この記事では主に「バグが発生しにくいこと」「バグが発生しても原因を特定しやすいこと」を目的としている。
※具体的なコード例を載せると長くなるので割愛。文字での説明のみ。わかりにくいのは承知の上。
目次
名付けについて
- 理解までの時間が最短か
- 実態を表しているか
- 誤解を生まないか
正直これについては、感覚的な部分や語彙力(英語)に依存する部分であるので、コメントしたからと言って一朝一夕で身につくものではない。
習慣として他人が書いた「筋の良い」コードを読むのが力を身につけるための王道だろうか。
引数について
- 引数によって過剰に挙動を制御していないか
- メソッド名から引数を予想できるか(最も自然な引数になっているか、驚き最小の法則)
前者については別のメソッドやクラスに切り分けよう。
戻り値について
- 失敗を表すのに null や false を使っていないか
- 空の結果を返すのに null や false を使ってないか
- 戻り値に型が混在していないか
1 つめについては例外を使いましょう、というお話。 null や false では「その時点」ではプログラムが動き続けてしまう。 もし戻り値チェックが行われなかったらおかしなデータのまま後段の処理に進んでしまい予期せぬ挙動を引き起こす原因になる。
2 つめについては空配列や空文字列を使いましょう、というお話。 ただし数値の場合は議論の余地があり、場合によって null を使うのもやむなし、ということもある(0 や負値をとり得る数値の場合)。
データとその型には意味があって、意味に沿ったプログラミングをすれば記述は自然なものになる。 null や false を返していたら都度戻り値チェックをしなければいけないが、空配列を返しているなら、配列が来ることを想定している後段の処理にそのまま渡して問題ない(場合が多い)。
余分な処理が増えれば当然コーディングの量が増えて生産性は下がるし、バグが入り込む余地も増える。
3 つめは「処理の結果によって数値が返ってきたり、配列が返ってきたりする」みたいなことになっていないか、というお話。 実は2つめの内容を内包している。
期待される型が 1 つだけなら、後段の処理も1種類の型を想定すれば済む。
オブジェクト指向プログラミングなら継承の仕組みもうまく使いたいところ。
例外について
- 例外を握りつぶしていないか
- 失敗等のときにすぐに例外を投げているか
パフォーマンス面を気にするのであれば、また事情は変わってくるが。
責任範囲について
- 1 メソッドが大きすぎないか
- 複数箇所のデータにアクセスしていないか
- 一言で表すことができる名前をつけられるか
名付けに悩んで良い答えが出ないときは、往々にして設計を見直したほうが良いという場合がある。
既存のプログラムについて
- すでに「それ」を実現できる組み込みまたは公開されている関数・クラスはないか(車輪の再発明)
- 低レイヤーの処理をよしなに wrap してくれているものはないか
- 既存のものを使うとき、「イケてない」仕様を wrap してあげられないか
2 つめの例を挙げるなら PHP における curl に対する Guzzle のようなもの。
その他
- 余分な処理をしていないか
- ネストを少なくできないか
- クラスやメソッドの階層・粒度が一致しているか
- 処理が何かの文脈に依存していないか
3 つめの話は設計の領域に入ってくるので、少し抽象度が高く伝わりにくいかも。
4 つめは「暗黙の前提条件を満たさないと正しく動かない」ということがないか、というお話。
「メソッド B は先にメソッド A を呼び出してから使わなければいけない」とか。 この場合、メソッド A の戻り値となるクラスの方にメソッド B を生やすなどして、間違って使われる余地が少なくなるような設計にすると良い。
その他、感覚レベルの話(オカルト含む)
- コードの文字の密度が高すぎないか
→ 集中力が分散し、「見落とし」が起こりやすくなる。
- コードに対称性はあるか
→ 対称性があると「異物」を見つけやすい。前節で説明した「階層」「粒度」が揃っているかが分かりやすい。
- ざっと見渡したときに「違和感」がないか
→ ここまでに説明した内容が守られていると、コードは「美しい」
余談
ここまでまとめてきた内容は、概ね次の3つの資料でカバーされていると思う。
- リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)(書籍)
- プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則(書籍)
- PHP7 で堅牢なコードを書く - 例外処理、表明プログラミング、契約による設計 / PHP Conference 2016 // Speaker Deck(@t_wada さんによる PHP Conference 2016 の講演資料)