🔖

『開発プロフェッショナル 〜コメントの流儀〜』コメントの考え方・実践ルール・コメント駆動開発について

2024/02/25に公開

こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、開発するときに、私が実践しているコメントの考え方や、実践ルールなどについて、ご紹介していきます。

コメントに対する考え方・なぜコメントを残すのか?

コメントは、プログラムのSummary(処理内容・役割など)や、
SrcCodeから読み取れない情報(要件・仕様など)などを説明して、開発をサポートするために存在します。

1. コメントは未来の自分やTeamメンバーのためのものである

まず、あたりまえですが、人間は忘れます。。。🥺
1年前に書いたCodeの内容をパッと出されて説明してくださいと言われて、どこまで説明ができるでしょうか?
複雑性の少ないある程度、簡単なCodeなら、すぐに答えられると思います。
ただ、機能が豊富な大規模なプロジェクトだったり、多くの人が開発に携わったりすると、どうしてもCodeの複雑性が増したりします。。。
さらには、 前提となる仕様・要件の知識や、前処理の知識が必要 で、すぐに解読ができないことなどもたびたびあったりします。。。😭

上記のような悲劇を味わったことのある人なら、コメントの有用性・重要性は、よくわかっているはず!

コメントは、未来の自分や、チームメンバーに対する共有物の1つ です。
(もちろん、SrcCodeそのものも共有物です)
コメントという言語的説明で、後から携わる人がわかりやすいようにSrcCodeを整備するのも重要なコミュニケーション・共有スキルだと思っています。

2. プログラムに書かれていないことを説明する必要がある

要件や仕様のような前提知識のようなもの、ドメイン知識、前処理など、プログラムに書かれていないことを記述するのも、コメントの大事な役割です。
つまり、プログラムに書かれていない重要事項・注意事項は、コメントで説明する必要もあるということです。
(もちろん、開発Docsも必要ですが、読むのをたまに忘れる。。。🥺)

3. コメントもプログラムの1つでありメンテすべきものである

冒頭に説明したとおり、コメントは、プログラムのSummary(処理内容・役割など)や、SrcCodeから読み取れない情報(要件・仕様など)などを説明して、開発をサポートするために存在します。

あたりまえですが、

  1. プログラムのSummary(処理内容・役割など)
  2. SrcCodeから読み取れない情報(要件・仕様など)
    などの開発を取り巻く環境は、変化していきます。

そこで、大事な考え方の1つが、 コメントもプログラムの1つでありメンテすべきものである という考え方です。
(めっちゃ、あたりまえですが。。。)

SrcCodeの処理内容が変わったり、役割が変わったらコメントも合わせて、メンテをするようにしましょう。
また、要件・仕様の変化で、SrcCodeが変化したのなら、それに合わせて記述済みのコメントも修正しましょう。

コメント・テクニック Ver. JavaScript/TypeScript

コメントに対する考え方・重要性が伝わったと思うので、続いて、実践的なコメント・テクニックについてご紹介していきます。
私のメインの使用言語が、JavaScript/TypeScriptなので、JavaScript/TypeScriptをベースに説明しますが、書き方のポイントなどは、他の言語でも使えるはずです。

JavaScript/TypeScriptでのコメント記法(JSDoc/TypeDoc)

JavaScript/TypeScriptのコメントの残し方と言えば//だと思いますが、コメントをしっかりと残すようなところでは、ぜひ/** */の記法(JSDoc)を使いましょう。

この/** */の記法(JSDoc)には、次のような特徴・機能があります。

  1. 関数,クラス,変数,プロパティなどに対するコメント情報(コメント・ヒント)を表示してくれる。
  2. コードを記述する際のCode補完をしてくれる。
    • コメント情報も表示してくれる。
  3. @paramで引数や、@return(@returns)で返り値、@typeで型の情報などを明示的に記述できる。

試しに次のようなフリー検索を実行する関数に対して、コメントを残している場合で考えてみます。

/**
 * NOTE: フリー検索 Box の検索処理
 *
 * - 配送先(住所)リスト 内を フリー検索できる
 * - 検索条件に部分一致する 配送先リストだけを表示する
 * - 次の3つの条件で部分一致するかどうかを判定する
 *    - アドレス (住所・文字列) との部分一致
 *    - フルネームとの部分一致
 *    - 電話番号との部分一致
 * @param {Array} addressList 送付先(住所)リスト
 * @param {String} searchQuery 検索・文字列
 * @return {Array} 部分一致する 送付先(住所)リスト
 */
const searchFunction = (addressList, searchQuery) => {
  /** 検索に部分一致する 送付先(住所)リスト */
  const matchAddressList = [];

  /** 部分一致パターン・正規表現 */
  let searchQueryRegExp = new RegExp(searchQuery);
  console.log("searchQueryRegExp", searchQueryRegExp);

  // 送付先(住所) を 1つずつ検索する
  addressList.forEach((address) => {
    /** 送付先(住所) */
    const addressStr = `${address.province}${address.city}${address.district} ${address.building} ${address.address_line1}`;
    /** フルネーム */
    const fullName = address.full_name;
    /** 電話番号 */
    const telNumber = address.phone_number;

    // 検索文字列が 送付先(住所)・フルネーム・電話番号 の文字列と、部分一致するかどうかを判定する
    const isMatch =
      searchQueryRegExp.test(addressStr) ||
      searchQueryRegExp.test(fullName) ||
      searchQueryRegExp.test(telNumber);

    // 部分一致する 送付先(住所)リスト を追加する
    if (isMatch) {
      matchAddressList.push(address);
    }
  });

  return matchAddressList;
};

searと途中まで入れた段階で、Code補完機能でサジェストしてくれています。
さらに言うと、コメントの内容も表示しれてくれるので、大助かりです。

また、すでに記述している関数・呼び出しに対しても、カーソルをあてると、Code・ヒントを表示してくれます。

JSDocは、Markdown書けるんやで🌟

先述のフリー検索を実行する関数に対するコメントの書き方で気づいた方もいるかもですが、
JSDoc(/** */)の記法では、実はMarkdownも書けます🙌✨
この記事を読んでいる方には、ぜひこのポイントも押さえた上で、コメントを残してもらいたいです💪🥺

例えば、次のような型定義に対するコメントをMarkdownで書いていきます。

/** プロファイリング Model */
export interface Profiling {
  id: number;
  create_time: string;
  /**
   * NOTE: 更新日時
   * 1. 初回生成時は、create_time と update_time は同じ日付が入る
   * 2. 2回目以降は update_time だけが更新される
   */
  update_time: string;
  deleted: 1 | 0;
  /** プロファイリング本文 */
  text: string;
}

const profiling: Profiling = {
  id: 1,
  create_time: "2024/01/01 00:00:00",
  update_time: "2024/01/01 00:00:00",
  deleted: 1,
  text: "text",
};

const update_time = profiling.update_time;

コメントを残した型定義のプロパティにカーソルをあてると、次のようにコメントがMarkdownで表示されていることがわかります。

JSDoc/TypeDocは、コメントからDocumentを生成することができる

今回は、Document生成の詳細まで解説はしないのですが、JSDoc/TypeDocはコメントからDocumentを生成するツールです。

JSDocでJavaScriptのドキュメントを作成する方法や、
TypeDocでTypeScriptのドキュメントを作成する方法に関しては、次の記事が解説してくれています🙆‍♂️
コメントからDocを生成するようなプロジェクトの場合は、この機能もぜひ活用していきましょう。

https://ics.media/entry/6819/

https://typedoc.org/example/

要件・仕様的な知識をコメントに記載する

コメントを残す際に、よく言われるのが 「なぜ、このような実装をするのか?」 わかるように書くということだと思います。
そして、この 「なぜ、このような実装をするのか?」 には、要件・仕様的な影響が多いです。
そこで、要件・仕様的な知識をコメントに記載する必要がある場合は、それもしっかりと記載しましょう。

/**
 * Update Button の Enable / Disabled 制御フラグ
 * - Default: false (Disabled・グレー で Button は押せない)
 * - true: 最新のData生成から 6ヶ月以上経過している場合は、Update 可能で、Button は押せる(Enabled・青色)
 * - false: 最新のData生成から 6ヶ月以内の場合は、Button は押せない (Disabled・グレー)
 */
const isEnableUpdate = false;

アノテーション・コメントを使いこなす

コメント・テクニックの1つとして、アノテーション・コメントというものがあります。
該当Codeの状態を端的に表すタグ的な役割のコメントのことをアノテーション・コメントと言い、
コメントでよく見るTODO:などがアノテーション・コメントにあたります。
ちなみに、アノテーション(annotation)とは、注釈という意味の英単語です。

よく使われているアノテーション・コメントを一覧にしてまとめると次のようになります。

記法 説明
NOTE: コードの意図や理由を記述する。
TODO: あとで追加、修正するべき機能など、やるべきTaskがある。
FIXME: 既知の不具合があるコード。修正が必要。
HACK: 動くけど、あまりきれいじゃないコード。リファクタリングが必要。
BUG: あきらかなバグがあるコード。修正が必要。
XXX: 危険なコード!動くけどなぜうごくかわからない。
REVIEW: コードのレビューが必要。意図した通りに動くか、見直す必要がある。
OPTIMIZE: 無駄が多く、ボトルネックになっている。
CHANGED: コードを変更した理由を記述する (コードをどのように変更したか)
WARNING: 警告の意味合い。注意が必要なコード。

アノテーション・コメントの管理に役立つ拡張機能: 『TODO Tree』

開発を進めていくにつれて、TODOが増えていき、後から見返すときに探しづらいことがあります。
そんな、アノテーション・コメントの管理に役立つVSCodeの拡張機能でおすすめなのが『TODO Tree』です。

https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree

これらの機能について、この後、解説していきます。

アノテーション・コメントをハイライトする機能

『TODO Tree』のアノテーション・コメントをハイライトする機能では、次の画像のように設定されたアノテーション・コメントをハイライトしてくれます。

『TODO Tree』のDefaultで、ハイライトされるアノテーション・タグは、
"BUG", "HACK", "FIXME", "TODO", "XXX"の5つに設定されています。
この設定は、任意に変更することができるので、次のようにして、"WARNING"も追加してみます。
(setting.jsonで、設定を追加できます👌)

setting.json
"todo-tree.general.tags": ["BUG", "HACK", "FIXME", "TODO", "XXX", "WARNING"],

上記の設定でUpdateすると、"WARNING"もハイライトされるようになりました🙌

アノテーション・コメントの一覧表示をする機能

続いて、アノテーション・コメントの一覧表示をする機能についてもご紹介します。
VSCodeのSideBarに表示される『TODO Tree』のアイコンButtonをクリックすると、次のように現在開いているプロジェクト内のハイライト・対象が一覧表示されるようになっています✨

JSDocでもアノテーション・コメントがハイライトされるようにする

『TODO Tree』のDefault設定では、次のように//では、アノテーション・コメントがハイライトされますが、
/** */のようなブロックコメント内ではハイライトされていません。

JSDoc内の、アノテーション・コメントを『TODO Tree』で認識できるようにするためには、
次のような正規表現をVSCodeのsetting.jsonに追加設定する必要があります。

setting.json
"todo-tree.regex.regex": "(//|#|<!--|/\\*|^\\s*\\*)\\s*($TAGS)"

追加したことで、次のように/** */でもアノテーション・コメントがハイライトされるようになりました。

他の言語のコメント記法での正規表現についても、こちらのDocにまとまっています。

https://github.com/Gruntfuggly/todo-tree/wiki/Configuration-Examples

おすすめの追加設定・まとめ Ver.TS・JS使い向け

TS・JS使い向けの『TODO Tree』のおすすめ・追加設定は、まとめると次のような設定になります。
設定はsetting.jsonに追加します。

setting.json
"todo-tree.general.tags": ["BUG", "HACK", "FIXME", "TODO", "XXX", "WARNING"],
"todo-tree.regex.regex": "(//|#|<!--|/\\*|^\\s*\\*)\\s*($TAGS)"

GitHub Copilotと共に『コメント駆動開発』を実践しよう!

私は、たびたび社内のAI・LTや、以前に書いた記事などで、
GitHub Copilotを活用した『コメント駆動開発』という開発スタイルを推ししています。
この記事でも最後に、GitHub Copilotを活用した『コメント駆動開発』についてご紹介したいと思います。

https://zenn.dev/aiq_dev/articles/fda5063d2ff293#github-copilotでコメント駆動開発🌟

「コメントを書く = Copilotと対話する」という使い方ができる!

GitHub Copilotの使い方はシンプルで、 「コメントを書く = Copilotと対話する」 という感覚で使えます。
Copilotは、コメントやSrcCodeの状況から「あなたが次の書きたいCodeは、これだろ?」って感じで、
Codeの自動補完(提案)をしてくれます。
Copilotの何が嬉しいかと言うと、書いている途中に 「推論 -> 自動補完(Code提案)」 が実施されるので、Codeを書くスピードが、圧倒的に上がることです。


画像の出典:『ジョジョの奇妙な冒険』

GitHub Copilotで『コメント駆動開発🌟』

GitHub Copilotは、Code説明のコメントを書く習慣がある人には、特に嬉しいと思っています。
なぜなら、コメントからCodeを自動補完(提案)してくれるからです。

つまり、コメントの鬼である私が所望する 「コメント駆動開発」ができる! ができる点でも、GitHub Copilotは優秀なわけです。。。🥺
もう、話さないぞ、Copilot!!

なんなら、Codeを書いた後にコメントを追加しようとすると、コメントも提案してくれる。。。🥺
できるやつすぎるぞ、Copilot!!

まとめ

個人で、Blogもやっています、よかったら見てみてください。

https://masanyon.com/

注意事項

この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。

求む、冒険者!

AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨

詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。

参考・引用

https://zenn.dev/manase/scraps/bf17efbec26388

https://zenn.dev/aiq_dev/articles/fda5063d2ff293

https://www.npmjs.com/package/jsdoc

https://www.npmjs.com/package/typedoc

https://typedoc.org/example/

https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree

https://github.com/Gruntfuggly/todo-tree/wiki/Configuration-Examples

https://buildersbox.corp-sansan.com/entry/2022/08/08/110000

AIQ Tech Blog (有志)

Discussion