リーダブルコード 未来の自分を助ける 05

今回はリーダブルコードの5章より「読みやすいコード」とするために記載する「コメント」の重要な考え方について触れていきます。

www.oreilly.co.jp

本シリーズ:リーダブルコードの解説 各記事のリンクはこちらをクリック リーダブルコード 未来の自分を助ける 01 - こだわりデベロッパーズノート
リーダブルコード 未来の自分を助ける 02 - こだわりデベロッパーズノート
リーダブルコード 未来の自分を助ける 03 - こだわりデベロッパーズノート
リーダブルコード 未来の自分を助ける 04 - こだわりデベロッパーズノート
リーダブルコード 未来の自分を助ける 05 - こだわりデベロッパーズノート
リーダブルコード 未来の自分を助ける 06 - こだわりデベロッパーズノート

内容紹介

5章 コメントすべきことを知る

  • 5章 コメントすべきことを知る
    • 5.1 コメントするべきでは「ない」こと
    • 5.2 自分の考えを記録する
    • 5.3 読み手の立場になって考える
    • 5.4 ライターズブロックを乗り越える
    • 5.5 まとめ

5章ではコメントに何を書くのが良いのか? どのようなコメントを書くことで「読みやすいコード」になるのか? 逆に、どのようなコメント書くとかえって「読みにくいコード」になるのか?を解説しています。

人間はコメントに記載されていることを読まずに理解することはできません。 コメントが記載されていれば、そのコメントを読む分必要な時間が増えます。 そのため、読む価値のないコメントは「読みやすいコード」(読んで理解するまでにかかる時間が短いコード)とは真逆のものとなります。

それでは、価値のないコメントと価値のあるコメントの違いに触れていきましょう。

5.1 コメントするべきでは「ない」こと

以下に該当するコメントは改善しましょう。

  • コードを読んで直ぐに分かることをコメントする
  • 分かりにくい名前を解説するためにコメントする

コードを読んで直ぐに分かることをコメントする

このパターンのコメントで最も多いものが「自動生成機能」です。

javaであれば最近のIDEは「javadoc自動生成機能」を持っています。 この機能を利用して生成したjavadocをちゃんとメンテナンスしないと「コードを読んで直ぐに分かること」がjavadocに記載されます。

結果として、コメントを読んでも何ら得られる情報はなく、コメントを読む分だけ時間が増えてしまうことになります。

分かりにくい名前を解説するためにコメントする

変数名、定数名、クラス名、メソッド名などなど、ソースコードを書く際は常に命名と向き合う必要があります。

何時も素晴らしい命名ができれば良いのですが、残念ながらうまいこと命名できず、後から読んでみて分かりにくいと気が付く場合があります。 このようなとき、分かりにくい名前の解説にコメントを利用するのはやめましょう。

名前が良くないのであれば、それをコメントで補うのではなく、名前自体をもっとより良いものに変更しましょう。 「ひどいコード + 優れたコメント」よりも「優れたコード」の方が理解しやすく、保守もやりやすいです。

リーダブルコードの具体例

コードを読めば直ぐに分かる

以下のコメントはAccountクラスがどのような目的を持つクラスか?フィールドのprofitがどのような意味を持つかは何も説明されていません。

コードを読んで直ぐに分かることしかコメントされていないので、このコメントには価値がありません。ちゃんとコメントをメンテナンスして目的や意味を記載しましょう。

// Accountクラスの定義
class Account {
    // コンストラクタ
    public Account() { ... }

    // profitに新しい値を設定する
    public void setProfit(double profit) { ... }

    // このAccountからprofitを返す
    public double getProfit() { ... }
}
分かりにくい名前の解説

Replyの内容をルールに則って綺麗にしたいのでメソッド名に「clean(綺麗)」を使っています。

// Replyに対してRequestで指定した制限を適用する。
// 例えば、返ってくる項目数や、合計バイト数など。
void cleanReply(Request request, Reply reply) { ... }

しかし、ITでは「clean」という名前はデータを全て削除してまっさらな状態を表すことが多いです。 そのため、誤解を生まないように「clean」をコメントで説明しています。

このような場合は「enforce limit(制限を課す)」という名前にすればコメントが無くても理解できます。

// replyをrequestで指定された項目数やバイト数の制限に合わせる。
void enforceLimitsFromRequest(Request request, Reply reply) { ... }

5.2 自分の考えを記録する

コードを書いている時に考えていたことをコメントに記録することで、そのコードにどのような意図が有ったのか?を後から読んで理解できます。

「悩んだこと」「複数の方法から一つの方法を選んだ理由」など、自分がコードを書くために決断したときの「大切な考え」をコメントに記録しましょう。

  • コードを書いたときに考えたこと
  • コードに存在する欠陥
  • その値を定数とすることに決めた背景

コードを書いたときに考えたこと

コードを書く際に、複数の方法から一つを選ばなければならないときがあります。

トレードオフが発生する中で「何を選択して、何を諦めたのか?」をコメントとして記録しましょう。後世の人がコードを読んだとき、より大切としているものが何であるか?を読み取ることができます。

// ヒューリスティックだと単語が漏れることがあるが仕方ない。100%は難しい。

もし、どれを選んでも大差がないのであれば、それも記録しましょう。「ちゃんと考えて比較した結果、どれを選んでも差が無かった」という情報があれば、後世の人が「もしかして、これ検討が漏れてたんじゃないの?」と疑念を持つことがなくなります。

// nested loop結合で性能が悪かったのでmerge結合とhash結合を検証したが大差はなかった。

コードに存在する欠陥

技術、サービス、コードは進化を続けます。そのため、現時点では妥当であった方針が徐々に実情と合わなくなってくることがあります。このような、問題となることが分かったものはコードに記録しましょう。

現在はデータ量が少ないため問題ないものの、データ量が増えてきたら問題となることがあるのであれば、それを頭と心に留めるのではなくコメントに記録しましょう。

// 50万件までならArrayListで問題ない。50万件超えるならTreeListを検討した方が良い。

現在のリリースでは意図的に対応していないものがあるのであれば、それをコメントに記録しましょう。

// 1stリリースではJPEGのみ対応。他の画像フォーマットは今後のリリースで順次対応予定。

このようなコメントを残しておくことで、後世の人はどんな課題があるのか?どんな対応が予定されているのか?をコードから把握することができます。

その値を定数とすることに決めた背景

とある値を定数とすることを決めた場合、その値には「システム的な理由」か「業務的な理由」があるはずです。

どのような理由からこの定数を作ったのか?背景をコメントに残しておきましょう。

定数名をちゃんと付けていれば、定数がどんな意味を持つのか?は定数名とその値から読み取れます。しかし、その値にした背景を読み取ることはできません。 コメントに記録することで、その値を定数としたときの「大切な考え」を残しておきましょう。

後々その定数を変更する必要があるのか?ないのか?を判断する際にとても役立ちます。

// 同時に実行するワーカースレッドの数
// 性能試験の結果、処理時間、CPU消費量、メモリ消費量のバランスが良い数が8だった
public static final int NUM_THREADS = 8;

5.3 読み手の立場になって考える

この内容は経験がものを言う部分が大きいです。そのため、若手エンジニアの方にはちょっと難しいかと思います。

若手エンジニアの方は、自分が実際にその状況になった場合にコメントに記録するところから始めてみましょう。

  • 質問されそうなことを想像する
  • ハマりそうな罠を告知する
  • 「全体像」のコメント

質問されそうなことを想像する、ハマりそうな罠を告知する

若手エンジニアの方が、自分の書いたコードに対して思案を巡らせながら実装するのはなかなかにハードルが高いです。 そのため、まず最初は自分が経験したことをコメントに記録してみましょう。

自分が悩んで質問したことは、後世の人も同じように悩んで質問する可能性が高いです。 自分がハマったことは、後世の人も同じようにハマる可能性が高いです。

自分が質問したこと、自分がハマったことをコメントに記録することで、後世の人が同じ轍を踏まないようにしてあげましょう!

「全体像」のコメント

こちらも若手エンジニアの方にはなかなかに難しい内容となっています。

自分が担当する箇所に関して、自分が何のために何をしようとしているかを把握しながら進めるために、大まかにやりたいことをコメントするのは良い方法です。

まずは自分が担当している範囲を中心に、全体像を把握する練習と合わせてコメントしてみましょう。

5.4 ライターズブロックを乗り越える

コメントをどのように書こうか悩んでしまい、結局書かなかったというのはあるあるではないかと思います。

とは言っても、コメントを書かないことには慣れていくことができません。だからこそ、自分の頭で考えている内容をとりあえず書いてみましょう。 後で読み返してみて不要だと感じたら改めて消せば問題ありません。

リーダブルコードでは「ヤバイ。これはリストに重複があったら面倒なことになる」と思ったら、それをそのままコメントに書けば良い。と言っています。 このコメントがあるだけでも、後世の人は潜在的な課題が存在していることを把握できます。

慣れるためにも、まずは頭の中にある大切な考えをそのまま書き出してみましょう!

まとめ

本記事では、リーダブルコード5章の内容を解説しました。

最初の方では「コメントに書かないこと」、最後の方では「コメントに書くこと」を解説しています。

慣れるまでは、「このコメントは書いた方がいいのだろうか?価値が無いのなら書かない方がいいのだろうか?」と悩むこともあるのではないかと思います。

とりあえず頭に浮かんだことを書いてみましょう!「ライターズブロックを乗り越える」これが非常に重要です。

悩んだら「書きましょう!」

書かないことには慣れないですし、コメントを考える練習もできません。書いていればレビューで指摘を受けてより良い方法を学ぶこともできます。

コメントを書くことで「この実装もうちょっと綺麗にできるな」とか「この名前は分かりにくいな」とか気が付く点もありますので「物は試し」まずは書いてみましょう!