| name | code-prose-writing |
| description | コード内のコメント、TODO コメント、テストケース名、コミットメッセージの文章規範。書く内容の取捨選択(ドメインの言葉による方針、過剰な why の抑制、経緯と指示の排除)と、文の型・語彙の制限(「〜すれば〜できる」構文、直訳調、擬人法、比喩、誇張、攻撃的な語、括弧による強調、接続詞の省略、並列でない箇条書きの禁止)を定める。コメントを書くとき、テスト名を付けるとき、コミットメッセージを作るとき、およびそれらを推敲するときに使用する。 |
コメント・テスト名・コミットメッセージの文章規範
コメント、テストケース名、コミットメッセージを書く・直すときは、以下に従う。
記述する言語は周囲の記述に合わせる。直訳調の禁止は日本語で書く場合に適用し、それ以外の規範は言語を問わず適用する。
英語で書く場合、無生物を主語に置く形(The service retries failed calls.)は擬人法にあたらない。接続詞の規範は、文頭に関係を示す語を置く形(Instead, Because ...)と、等位接続詞で一文にまとめる形のどちらでも満たす。
一つの記述に複数の規範がかかり、両立しないときは、ドメインの言葉で書くほうを選ぶ。ただし、言い換えた結果、何が起きるのかが読み取れなくなる場合は、読み取れる書き方を選ぶ。
規範が、依頼された変更の範囲の外にまで及ぶときは、範囲の外は直さない。該当する箇所を報告するにとどめる。範囲は記述の種別で数える。テスト名の付け直しを依頼されたなら、隣にあるコメントは範囲の外である。
何を書くか
- ドメインの言葉で方針を書く。実装手段の説明は、方針だけでは読めない箇所に限る。
- 悪い例:
// 注文を Map に詰め替えて O(1) で引けるようにする
- 良い例:
// 同一の顧客からの注文はまとめて 1 件として扱う
- why は必要な分だけ書く。コードを読めばわかる理由、一般的な設計上の常識、背景の説明を並べない。理由を書くのは、コードの見た目に反する判断をしている箇所に限り、一文で足りることが多い。
- 悪い例:
// 可読性と保守性を高めるため、責務を分割している。これにより変更時の影響範囲が限定され、テストも書きやすくなる
- 良い例:
// 締め日をまたぐ注文は前月分として集計する
- 変更の経緯を書かない。以前の実装、修正の履歴、途中で試した方法は、コメントとテスト名に残さない。コミットメッセージだけは例外とする。
- 悪い例:
// もともとは同期処理だったが、非同期に変更した
- 良い例:
// 集計の完了を待たずに応答を返す
- 指示や指摘を書かない。会話やレビューの内容を知っている前提の記述も書かない。読み手はコードだけを見ている。
- 悪い例:
// 指摘のとおり、ここではバリデーションを行わない
- 良い例:
// 入力の検証は呼び出し元で済んでいる
文の型
- 「〜すれば〜できる」の構文を使わない。条件と効果の説明ではなく、対象が何であるか、何をするかを書く。
- 悪い例:
// このフラグを立てれば、キャッシュを無効化できる
- 良い例:
// キャッシュを使わずに毎回取得するフラグ
- 接続詞を省略しない。二文以上を並べるときは、文と文の関係がわかる語を文頭に置く。接続詞を補って文が増えるときは、先に文をまとめて数を減らし、そのうえで残った文に接続詞を置く。
- 悪い例:
// 再試行はしない。呼び出し元が失敗を扱う
- 良い例:
// 呼び出し元が失敗を扱う。そのため、ここでは再試行しない
- 並列でない内容を箇条書きにしない。前提、手順、注意のように役割の違うものを並べるときは、文でつなげて書く。
- 括弧による強調を多用しない。「」は引用と、誤読を招く語の明示に限る。
- 悪い例:
// ここでは「正規化」した「値」を「一時的に」保持する
- 良い例:
// 正規化した値を、書き込みが終わるまで保持する
- 平凡な文にする。読ませる工夫や言い回しの工夫を加えない。
語彙
- 英語の比喩的な名詞をカタカナのまま持ち込まない。ゲート、ガードレール、ハンドオフ、パイプライン、ソースオブトゥルースのような語は、日本語では何を指すのかが伝わらない。何をする箇所なのかを普通の言葉で書く。
- 悪い例:
// 保存前の品質ゲート
- 良い例:
// 保存する前に、必須の項目が入力されているか確認する
- 悪い例:
// 集計処理へのハンドオフ
- 良い例:
// ここから先の計算は集計処理で行う
- 悪い例:
// 設定のシングルソースオブトゥルース
- 良い例:
// 設定の値はこのファイルだけに書く
- 英語の構文をなぞった言い回しを使わない。「〜を可能にする」「〜に責任を持つ」「〜を提供する」のような形は、動詞をそのまま日本語に置き換えたために不自然になっている。主語と動詞を日本語の並びで書き直す。
- 悪い例:
// 呼び出し元が独自の書式を指定することを可能にする
- 良い例:
// 呼び出し元で書式を指定できる
- 悪い例:
// このクラスは在庫数の整合性に責任を持つ
- 良い例:
// 在庫数の整合性はこのクラスで保つ
- 擬人法を使わない。コード、クラス、サービスを、意思や感情を持つものとして書かない。
- 悪い例:
// このクラスは在庫の状態を知っている
- 良い例:
// このクラスが在庫の状態を保持する
- 比喩を使わない。対象をそのまま指す語で書く。日常的に使われていて気付きにくい比喩も同じく避ける。
- 悪い例:
// リクエストの門番として働く
- 良い例:
// 権限のないリクエストをここで止める
- 悪い例:
// 必須の項目が埋まっているか確認する
- 良い例:
// 必須の項目が入力されているか確認する
- 誇張した表現、物語のような表現を使わない。
- 悪い例:
// 劇的に性能を改善する魔法のようなキャッシュ
- 良い例:
// 同じ問い合わせの結果を再利用する
- 強すぎる言葉と攻撃的な表現を使わない。禁止や警告を伝えるときも、何をすればよいかを事実として書く。
- 悪い例:
// 絶対に触るな。壊れるぞ
- 良い例:
// 値を変えるときは、集計側の丸め処理も合わせて直す
コメント
- コメントは、名前と引数だけでは読み取れない前提、制約、判断がある箇所に付ける。名前から読み取れることを言い直すだけの箇所には付けない。
- コードをそのまま日本語に置き換えただけのコメントを書かない。コードに定数や引数として現れている値も、コメントで繰り返さない。
- 既にあるコメントの推敲を依頼されたときは、書き直しに加えて、名前から読み取れることを言い直すだけのコメントを消す。
- 関数やクラスに説明を付けるのは、名前と引数から読み取れない前提や制約があるときに限る。付けるときは、何をするものかを先に書き、制約や例外的な扱いをそのあとに続ける。
- コメントは、判断が 1 行に現れる場合はその行の直前に置く。判断が複数行にまたがる場合は、その先頭の行の直前に置く。
- 仮実装として残す箇所には
// TODO: を付け、そのあとに、本来どうするべきかを書く。書き方はほかのコメントと同じで、ドメインの言葉で方針を書き、経緯や指示には触れない。
- 悪い例:
// TODO: あとで直す
- 悪い例:
// TODO: 指摘のあったレートの扱いを直す
- 良い例:
// TODO: 為替レートは固定値ではなく、注文日のレートで計算する
- 仮実装ではない箇所に
TODO を付けない。一時的なメモ、作業中の覚書、自分への問いかけも残さない。
テストケース名
- 条件と期待する結果を書く。「〜のとき、〜する」「〜の場合、〜を返す」のような形にする。これらは例示であり、条件と結果の両方が読み取れるなら別の形でもよい。
- 悪い例:
金額を指定すれば合計が計算できる
- 良い例:
注文が複数あるとき、金額の合計を返す
- 条件と期待する結果の両方をドメインの言葉で書く。内部の実装名や型名で表さない。検証に使う関数に由来する言い方(例外を投げる、エラーにならない など)も、業務の上で何が起きるかに言い換える。
- 条件には、テストに渡す引数の形ではなく、その引数が業務の上で表しているものを書く。
- 例外を投げないこと、値が空でないことのように、何が起きないかだけを確かめるテストでは、その検証が通ったときに業務の上で成り立っている状態を書く。
- 悪い例:
顧客が休止中のとき、エラーにならない
- 良い例:
顧客が休止中のときも、請求額を計算する
- 悪い例:
orderList が空配列のとき、例外を投げる
- 良い例:
注文が 1 件もないとき、集計を拒否する
- 修正の経緯を名前に含めない。
- 悪い例:
リグレッション:以前落ちていた締め日の計算
- 良い例:
締め日をまたぐ注文は、前月分として集計する
- 「正しく動く」「正常に処理される」のように、何を確かめるのかがわからない名前にしない。
コミットメッセージ
- 既存の履歴の形式に合わせる。接頭辞の有無、記述の言語、件名の書き方を揃える。
- 接頭辞を使う履歴では、種類を変更の目的で選ぶ。利用者から見た不具合が解消される変更は fix、外から見た振る舞いが変わらない整理は refactor とする。範囲を表す語は、既存の履歴で同じ領域に使われているものに合わせる。
- 件名には、この変更が何をするものかを書く。効果や可能になることではなく、変更そのものを書く。
- 悪い例:
設定を変えれば言語ごとの起動が速くなるようにした
- 良い例:
disable language runtime support in neovim
- 本文は必要なときだけ書く。件名だけでは判断の理由がわからない場合に、数文で書く。
- 本文に書くのは判断の理由と以前の状態に限る。変更したファイルの一覧や、付随して直したテストのような差分の内訳は書かない。
- 変更の経緯を書いてよい。以前の状態、その状態で起きていたこと、変更後の状態の順に書く。
- 指示や指摘は書かない。依頼を受けたこと、レビューでの指摘、会話の流れには触れず、変更の内容と理由だけを書く。
- 悪い例:
レビューでの指摘に対応して、リトライ処理を削除した
- 良い例:
リトライ処理を削除する。呼び出し元でも再試行しており、同じ要求が二重に送られていた
書いたあとの点検
書き上げたら、次を順に確認する。
- 「〜すれば〜できる」の形が残っていないか。
- 以前の実装や修正の経緯に触れていないか。コミットメッセージ以外では残さない。
- 会話やレビューを知らない読み手が、そのまま読めるか。
- 理由の説明が、判断の要点を超えて続いていないか。
- 実装手段の説明が先にあり、ドメインの言葉による方針が後回しになっていないか。
- 英語の比喩をカタカナにした語、英語の構文をなぞった言い回し、擬人法、比喩、誇張、強すぎる語が混じっていないか。
- 「」による強調が並んでいないか。
- 箇条書きの各項目が、同じ役割の並列になっているか。
- テスト名と、その近くのコメントが同じ内容を述べていないか。同じなら名前に残し、コメントは名前から読み取れない事情に限る。
- 二文以上あるとき、文と文の関係を示す語が文頭に置かれているか。