3. コメントを正しく活用する
コメントを残すとコードが読みやすくなります。また、XML形式でコメントを書くとクラスやメソッドの情報をIDEからマウスホバーで確認できるようになります。publicなフィールドやメソッドなどで使うと良いです。
/// <summary>
/// 対象にダメージを与える
/// </summary>
/// <param name="target">ダメージを受ける対象</param>
/// <param name="amount">ダメージ量</param>
public void ApplyDamage(IDamageable target, int amount)
{
target.TakeDamage(amount);
}しかし、コメントは実は注意していないとバグの原因になり得ます。
コメントを退化させない
メンテナンスが疎かになり情報が古くなったコメントを退化コメントといいます。退化コメントとは、言ってしまえば嘘をついているコメントです。そうなれば読み手は混乱し、バグの原因になります。実装を変更したならコメントの更新も忘れないようにしましょう。
退化しやすいコメントとして、ロジックの挙動をなぞるだけのコメントが挙げられます。コードの変更のたびにコメントを更新しなくてはならず、また、ロジックをそのまま書き起こしたつもりでもうっかり間違ったことを書いてしまうかもしれません。しかも結局その内容は該当箇所のコードを読めば分かるし一番正確です。結局、あまり理解の助けにならない上に害をなす可能性があり、役に立ちません。
// ❌ 退化コメント: 元々HPを10回復する処理だったが、任意の量を回復するように変更されたのにコメントが更新されていない
// プレイヤーのHPを10回復する ← 嘘つき!!
public void HealPlayer(int amount)
{
currentHitPoint = Mathf.Min(currentHitPoint + amount, maxHitPoint);
}// ❌ ロジックをなぞるだけのコメント: コードを読めば分かるし退化もしやすい
// currentHitPointにamountを加算し、maxHitPointを超えないようにする ← それはコード見れば分かるよ!!
public void HealPlayer(int amount)
{
currentHitPoint = Mathf.Min(currentHitPoint + amount, maxHitPoint);
}コメントでクソコードを誤魔化さない
以下のような言葉があります。
コードはユーモアのようなものだ。説明しなければならないなら、それはダメなものだ。
(Code is like humor. When you have to explain it, it’s bad.)
Cory House
つまり、適切に命名し整理され、読めば動作が分かるような自己文書化されたコードであればコメントは不要で、逆に、コメントで動作を説明しなければいけないならば、それは悪いコードであるということです。もしクソコードをコメントによって誤魔化しているのであれば、コメントを書くのではなくコメントを書かなくて済むようにコードを修正しましょう。
// ❌ Bad: コメントがないと理解できないコード
// HPが0以下で攻撃力が10以上なら特殊スキル、それ以外で防御力が5以上なら回復
if ((hp <= 0 && atk >= 10) || (hp > 0 && def >= 5))
{
// ...
}
// ✅ Good: コメントがなくても読めば分かる
bool canUseSpecialSkill = IsDead() && HasHighAttack();
bool canHeal = IsAlive() && HasHighDefense();
if (canUseSpecialSkill || canHeal)
{
// ...
}動作ではなく目的を伝える
良いコメントとは、「動作」ではなく「目的」を伝えるものです。コードが読まれる機会の多くは、保守か仕様変更のときでしょう。そこで読み手が気になるのは、「このロジックの目的は何か、何を意図して動いているか」です。動作はコードを適切に記述すればコメントが無くても明らかですが、その目的は簡単には読み解けません。なので、動作の代わりに、ロジックの目的や仕様変更時の注意点をコメントするのが良いです。
// ❌ Bad: 動作を説明するコメント
// リストをループして、HPが0以下の敵を削除する
enemies.RemoveAll(e => e.HitPoint <= 0);
// ✅ Good: 目的を伝えるコメント
// 倒した敵をフィールドから除外する
enemies.RemoveAll(e => e.HitPoint <= 0);// ✅ Good: 目的や注意点を伝えるコメントの例
// ダメージ計算の順序を変えるとバランスが崩壊するので注意
int rawDamage = baseAttack * comboMultiplier;
int reducedDamage = rawDamage - target.Defense;
int finalDamage = Mathf.Max(reducedDamage, 1); // 最低1ダメージは保証する仕様