リーダブルコード(The Art of Readable Code)の読書ノートです。今回の記事では、第5章「コメントすべきことを知る」と第6章「コメントは正確で簡潔に」について、コメントの書き方を紹介します。
コメントすべきではないこと
1. コードからすぐに推測できるようなこと
例えば:
// ユーザークラスの定義
class User {
// コンストラクタ
constructor() {}
// ユーザー情報を更新
updateProfile(user.info) {}
// ユーザー情報を取得する
getProfile(user.id) {}
}
ただ時間の無駄です。
2. 悪い名付けのせいで
コメントより、まずは適切な命名をしてほしい、関数名自体を改善すべきです。
// 悪い例
// リクエストで指定された制限(アイテム数や合計バイトサイズなど)を適用する
function cleanReply(request, reply) {
// ...
}
// 良い例
function enforceReplyLimits(request, reply) {
// ...
}
コメントすべきこと
1. 読み手の立場になって考える
もちろんコメント自体は別に新しい情報を提供できるわけではないけど。読み手の立場になって考えると、このコメントがあれば、所要な理解時間が短くなるから助けます。
// '*'の2番目以降を削除する
const name = line.split('*').slice(0, 2).join('*');
2. TODOコメント
改善が必要な箇所には、TODOコメントを残しておくと良いでしょう。
// TODO: この関数の実行時間を最適化する
function slowOperation() {
// ...
}
// FIXME: メモリリークの可能性あり
function potentiallyLeakyFunction() {
// ...
}
ぜひ読んでみてください:
アノテーションコメントのススメ|種類、一覧も紹介
3. 定数のコメント
定数の値がどのように決定されたのか、どのような意味を持つのかを説明するコメントは、読み手(半年後の自分でも含む)にとしてはとても重要です。
const NUM_THREADS = 8; // プロセッサ数の2倍以上であれば十分
const MAX_RSS_SUBSCRIPTIONS = 1000; // 人間が読める量に制限
const IMAGE_QUALITY = 0.72; // 品質のバランスと判断したユーザーテストで最適なサイズ
4. 全体像を説明するコメント
ファイルやクラスの冒頭に、そのコードの役割や他のコードブロックとの関係を説明するコメントを書くと、読みての理解を助けます。
/**
* UserManager クラス
*
* このクラスはユーザーの作成、認証、プロファイル管理を行います。
* データベースとの直接のやりとりは DbConnector クラスを通じて行います。
* セッション管理には SessionHandler クラスを使用します。
*/
class UserManager {
// ...
}
5. ブロック単位で要約コメントを残す
関数の中で複数の処理が走っている場合はブロック単位でコメントを書いておくと見やすくなる。
function generateUserReport() {
// ユーザーのlockを取得
// ...
// データベースからユーザー情報を読み込む
// ...
// 情報をファイルに書き込む
// ...
// ユーザーのlockを解放
// ...
}
コメントは正確で簡潔に
1. コメントをコンパクトに保つ
複数行のコメントを書かないといけない場合もありますが、できる限り簡潔に情報を伝えることを心がけましょう。
// 悪い例
// オブジェクトのキーはカテゴリータイプです。
// 値は配列で、1番目の要素はscore、
// 2番目の要素はweightです。
const scoreMap = new Map();
// 良い例
// CategoryType -> (score, weight)
const scoreMap = new Map();
2. 指示語の使用は避ける
「これ」や「それ」といった指示語は、参照先が不明確になる可能性があります。具体的な名詞を使用しましょう。
// 悪い例
// データをキャッシュに入れる。ただし、先のそのサイズをチェックする
この場合「その」が指しているものが「データ」なのか「キャッシュ」なのか分からない。
// 良い例
// データをキャッシュに入れる。ただし、先のデータサイズをチェックする
要するに、明確でないものに関しては使わないほうがよい。
3. 関数のコメントにエッジケースも書く
できるだけ詳細に記載しましょう。
// 悪い例
// ファイルの行数を返す。
function countLines(filename) { /* ... */ }
// 良い例
// ファイル内の改行文字('\n')の数をカウントして返す。
// 空のファイルや最後に改行のないファイルでは0を返す可能性がある。
function countLines(filename) { /* ... */ }
4. 入出力の例を使ってコメントする
特にエッジケースの場合。
// 文字列の先頭や末尾から文字を削除する
// 例: strip("abba/a/ba", "ab") は "/a/" を返す
function strip(src, chars) { /* ... */ }
5. コードの意図を書く
コードの処理をただコメントするのではなく、そのコードが何を目的であるのかを書こう。
function displayProducts(products) {
products.sort((a, b) => b.price - a.price);
// 悪い例
// 配列を逆に処理する
// 良い例
// 価格の高い順に各商品の価格を表示する
for (let i = 0; i < products.length; i++) {
displayPrice(products[i].price);
}
}
6. 情報量の多い言葉を使う
言葉遊びと思いますが、少ない文字数で最も多くの情報量を伝えられる言葉を使った方が良いです。
所感
コメントはプロジェクトを進めるための言わばコミュニケーションツールです。そもそもコメントがなくともプロジェクトが成立するですが、事前に目的を正しく理解し、チーム内で認識を合わせて、円滑に進むために、コメントを書くことが重要だと思います。