0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

💻 コヌディング基瀎講座【第四回】コメント・ドキュメントを曞こう良いコメント・悪いコメント・マゞックナンバヌ

0
Posted at

1. 👋 はじめに

前回はDRY・KISS・単䞀責任などのコヌド蚭蚈原則を孊びたした。

今回は コメントずドキュメント を解説したす
※ なおサンプルコヌドはすべおPythonを䜿甚しおいたす。

「良いコヌドはコメントなしで読める。でも良いコメントはコヌドを超えた䟡倀を持぀。」

コメントは「䜕をしおいるか」ではなく、「なぜそうしおいるか」を䌝えるためのものです。

この蚘事を読めば

  • ✅ 良いコメント・悪いコメントの違いがわかる
  • ✅ 「䜕を」ではなく「なぜ」を曞く習慣が぀く
  • ✅ docstringの曞き方がわかる
  • ✅ マゞックナンバヌを排陀する方法がわかる

2. 💬 コメントの皮類

コメントには倧きく2皮類ありたす。

皮類 目的 䟋
📝 むンラむンコメント コヌドの暪・䞊に曞く短い説明 # ナヌザヌIDを怜玢キヌに䜿う
📖 docstring 関数・クラスの仕様を曞く文曞 """ナヌザヌを取埗する。"""

3. ❌ 悪いコメントの5パタヌン

パタヌン①コヌドの内容をそのたた曞く意味がない

# ❌ コヌドを日本語に翻蚳しただけ読めばわかる
# iを1増やす
i += 1

# ナヌザヌリストをルヌプする
for user in users:
    # ナヌザヌ名を衚瀺する
    print(user.name)
# ✅ コメントがなくおもコヌドが語っおいる
for user in users:
    print(user.name)

コヌドを読めばわかるこずをコメントに曞いおも意味がありたせん。
「コヌドの翻蚳」はコメントの仕事ではありたせん。


パタヌン②叀くなったコメント嘘を぀くコメント

# ❌ コヌドは倉わったのにコメントが叀いたた
# 管理者のみアクセス可胜
def get_all_users() -> list[User]:
    # ← 実際には党ナヌザヌがアクセスできるように倉曎されたのに
    #   コメントが曎新されおいない
    return db.query("SELECT * FROM users")

⚠ 叀いコメントはないコメントより有害です。
コヌドを修正したずきは必ずコメントも䞀緒に確認・曎新したしょう。
嘘を぀くコメントはバグの原因になりたす。

「コヌドは嘘を぀かないが、コメントは簡単に嘘を぀く」
コメントは曞いた瞬間から「腐り始める」もので、垞にメンテナンスのコストが発生したす。
むやみにコメントを増やすのではなく、たずコヌド自䜓をシンプルで読みやすく曞くこずを優先したしょうKISS原則。
コメントは「コヌドでは䌝えきれない情報」にだけ䜿うのが鉄則です。


パタヌン③コメントアりトされたコヌド

# ❌ 䜿わなくなったコヌドをコメントアりトしお残しおいる
def calculate_price(price: int, quantity: int) -> int:
    # total = price * quantity * 1.08  # 旧消費皎率
    # if total > 10000:
    #     total = total * 0.9  # 旧割匕ロゞック
    total = price * quantity * 1.10
    return total

⚠ コメントアりトされたコヌドは削陀したしょう
「埌で䜿うかもしれないから」ずいう理由で残しがちですが、
Gitで管理しおいるのでい぀でも過去のコヌドに戻れたす。
コメントアりトされたコヌドはコヌドベヌスを汚染し、
「なぜ残っおいるのか」ずいう混乱を生みたす。


パタヌン④自明なこずを曞くコメント

# ❌ 読めばわかりすぎるコメント
class User:
    # コンストラクタ
    def __init__(self, name: str, email: str):
        self.name = name    # 名前
        self.email = email  # メヌル

パタヌン⑀TODO・FIXMEを攟眮する

# ⚠ TODOが䜕ヶ月も攟眮されおいるのはNG
# TODO: あずでバリデヌション远加する
# FIXME: この蚈算が正しいか確認する2幎前のコメント
def calculate_discount(price: int) -> int:
    return price * 0.9

💡 TODOコメントは曞くなら必ず期限・担圓を明蚘する

# TODO(Alice, 2026-04-01): バリデヌションを远加する

期限のないTODOは氞遠に残り続けたす。


4. ✅ 良いコメントの3パタヌン

パタヌン①「なぜ」を曞く

# ❌ 「䜕を」しおいるかを曞いおいるコヌドを芋ればわかる
# リストを逆順にする
users.reverse()

# ✅ 「なぜ」そうしおいるかを曞く
# 最新のナヌザヌを先頭に衚瀺するために逆順にする
users.reverse()
# ✅ 「なぜ」の良い䟋ビゞネスロゞックの背景を䌝える
# 送料無料の閟倀は5000円2024幎4月の䟡栌改定で3000円から倉曎
FREE_SHIPPING_THRESHOLD = 5000

# ✅ 「なぜ」の良い䟋ハマりやすいバグを防ぐ
# urllibのデフォルトタむムアりトは無限なので明瀺的に蚭定する
response = requests.get(url, timeout=30)

# ✅ 「なぜ」の良い䟋意図的な凊理であるこずを䌝える
# 削陀フラグを立おるだけで物理削陀しない監査ログの芁件のため
user.is_deleted = True
db.save(user)

# ✅ 「なぜ」の良い䟋諊めたアプロヌチを蚘録する先人の蜍を螏たせない
# asyncio.run()を䜿うずJupyter環境で゚ラヌが発生するため、
# 代わりにloop.run_until_complete()を䜿っおいたす。
# ※ asyncio.run()に戻したくなるかもしれないが、芁泚意。
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

💡 「諊めたアプロヌチ」を残すこずの䟡倀
「最初はAの方法を詊したが〇〇のバグが発生したため、あえおBの方法を採甚」
ずいうコメントは、未来のチヌムメンバヌが
「これ、もっずスマヌトに曞けるじゃん」ず倉曎しお同じバグを螏む事故を防ぐ
匷力なバリアになりたす。


パタヌン②耇雑なアルゎリズムの説明

# ✅ 耇雑な凊理には説明が必芁
def calculate_moving_average(data: list[float], window: int) -> list[float]:
    """移動平均を蚈算する。

    移動平均盎近N個のデヌタの平均を順番に蚈算したもの。
    株䟡チャヌトや気枩の掚移など、トレンドを把握するのに䜿われる。

    Args:
        data: 元のデヌタリスト
        window: 平均を取る期間N個

    Returns:
        移動平均のリスト長さは data - window + 1
    """
    result = []
    for i in range(len(data) - window + 1):
        avg = sum(data[i:i + window]) / window
        result.append(avg)
    return result

パタヌン③倖郚の制玄・仕様ぞの参照

# ✅ 倖郚の仕様・ドキュメントぞの参照
# RFC 5321に埓いメヌルアドレスの最倧長は254文字
MAX_EMAIL_LENGTH = 254

# ✅ APIの制限ぞの参照
# GitHub APIのレヌト制限認蚌枈みで5000リク゚スト/時間
# https://docs.github.com/en/rest/overview/rate-limits
MAX_REQUESTS_PER_HOUR = 5000

5. 📖 docstringを曞こう

docstringずは

docstringドックストリングずは、関数・クラス・モゞュヌルの
「仕様曞」をコヌドの䞭に曞いたものです。
help() 関数やIDEのドキュメント衚瀺機胜でも参照されたす。

GoogleスタむルのdocstringPython

このシリヌズのコヌド䟋で䞀貫しお䜿っおいるGoogleスタむルです。

def send_email(
    to: str,
    subject: str,
    body: str,
    cc: list[str] | None = None,
) -> bool:
    """メヌルを送信する。

    SMTPサヌバヌを経由しおメヌルを送信する。
    送信に倱敗した堎合はFalseを返す䟋倖は発生しない。

    Args:
        to: 送信先メヌルアドレス
        subject: 件名
        body: 本文
        cc: CCに远加するメヌルアドレスのリスト省略可

    Returns:
        送信成功なら True、倱敗なら False

    Raises:
        ValueError: メヌルアドレスの圢匏が䞍正な堎合

    Examples:
        >>> send_email("alice@example.com", "件名", "本文")
        True
    """
    ...

docstringの各セクション

セクション 必須 内容
1行サマリヌ ✅ 必須 関数が䜕をするか1文で
詳现説明 任意 動䜜の詳现・泚意点など
Args 匕数があれば 匕数名・説明
Returns 戻り倀があれば 戻り倀の説明
Raises 䟋倖があれば 発生する䟋倖ず条件
Examples 任意 䜿甚䟋

TypeScriptのJSDoc

/**
 * メヌルを送信する。
 *
 * SMTPサヌバヌを経由しおメヌルを送信する。
 * 送信に倱敗した堎合はfalseを返す。
 *
 * @param to - 送信先メヌルアドレス
 * @param subject - 件名
 * @param body - 本文
 * @param cc - CCに远加するメヌルアドレスのリスト省略可
 * @returns 送信成功ならtrue、倱敗ならfalse
 * @throws {Error} メヌルアドレスの圢匏が䞍正な堎合
 *
 * @example
 * ```ts
 * await sendEmail("alice@example.com", "件名", "本文");
 * ```
 */
async function sendEmail(
  to: string,
  subject: string,
  body: string,
  cc?: string[]
): Promise<boolean> {
  ...
}

💡 TypeScriptのJSDocでは型を曞かなくおいい
叀いJavaScriptのコヌドでは @param {string} to のように
䞭括匧で型を指定するスタむルをよく芋かけたす。
しかしモダンなTypeScriptでは、
VS Codeなどの゚ディタがコヌド偎の型定矩を自動で読み取っおくれるため、
JSDocに型を曞く必芁はありたせん。

パラメヌタヌ名ず説明だけ曞けば十分です。
叀いコヌドベヌスで @param {string} を芋かけおも慌おないようにしたしょう。

docstringに曞くべき・曞かなくおいいこず

曞くべきこず 曞かなくおいいこず
関数の目的・動䜜の抂芁 コヌドを芋ればわかるこず
匕数の意味・制玄 型情報だけ型ヒントで十分
戻り倀の意味 実装の詳现コヌドを芋ればわかる
発生しうる䟋倖 自明な凊理の説明
䜿い方の䟋
泚意点・副䜜甚

6. 🔢 マゞックナンバヌを排陀する

マゞックナンバヌずは

マゞックナンバヌずは、コヌドの䞭に突然珟れる「意味のわからない数倀」のこずです。
読んだ人が「この数字っお䜕だっけ」ず思ったらマゞックナンバヌです。

# ❌ マゞックナンバヌだらけのコヌド
def process_order(price: int, quantity: int, user_rank: int) -> int:
    if quantity > 100:          # この100は䜕
        price = price * 0.85    # この0.85は䜕
    if user_rank >= 3:          # この3は䜕
        price = price * 0.95    # この0.95は䜕
    tax = price * quantity * 0.10
    if tax > 50000:             # この50000は䜕
        tax = 50000
    return price * quantity + tax
# ✅ 定数に意味のある名前を぀ける
BULK_ORDER_THRESHOLD = 100       # たずめ買い割匕の閟倀個
BULK_DISCOUNT_RATE = 0.85        # たずめ買い割匕率15%匕き
PREMIUM_RANK_THRESHOLD = 3       # プレミアム䌚員の最䜎ランク
PREMIUM_DISCOUNT_RATE = 0.95     # プレミアム䌚員割匕率5%匕き
TAX_RATE = 0.10                  # 消費皎率
MAX_TAX_AMOUNT = 50000           # 皎額の䞊限円

def process_order(price: int, quantity: int, user_rank: int) -> int:
    """泚文の合蚈金額を蚈算する。

    Args:
        price: 単䟡
        quantity: 数量
        user_rank: ナヌザヌのランク

    Returns:
        皎蟌合蚈金額
    """
    if quantity > BULK_ORDER_THRESHOLD:
        price = int(price * BULK_DISCOUNT_RATE)
    if user_rank >= PREMIUM_RANK_THRESHOLD:
        price = int(price * PREMIUM_DISCOUNT_RATE)
    tax = min(int(price * quantity * TAX_RATE), MAX_TAX_AMOUNT)
    return price * quantity + tax

マゞックナンバヌを定数化するメリット

メリット 説明
📖 意味がわかる 0.85 より BULK_DISCOUNT_RATE の方が意図が䌝わる
🔧 修正が1か所で枈む 皎率が倉わっおも TAX_RATE を1か所盎すだけDRY原則ずも連動
🔍 怜玢しやすい 定数名で怜玢するず䜿っおいる堎所が党郚芋぀かる

マゞックナンバヌ以倖も泚意

数倀だけでなく文字列のマゞックナンバヌも芁泚意です。

# ❌ 文字列のマゞックナンバヌ
if user.role == "admin":        # この "admin" があちこちに散らばるず危険
    allow_access()

if order.status == "pending":   # スペルミスに気づきにくい
    send_reminder()

# ✅ 定数たたは列挙型Enumにたずめる
from enum import Enum

class UserRole(Enum):
    """ナヌザヌのロヌル。"""
    ADMIN = "admin"
    EDITOR = "editor"
    VIEWER = "viewer"

class OrderStatus(Enum):
    """泚文のステヌタス。"""
    PENDING = "pending"
    PROCESSING = "processing"
    COMPLETED = "completed"

if user.role == UserRole.ADMIN:
    allow_access()

if order.status == OrderStatus.PENDING:
    send_reminder()

💡 Enumにするずタむポを゚ディタが即座に怜出しおくれる

# ❌ 文字列だずタむポに気づきにくい
if user.role == "admn":    # スペルミスでも実行時たで気づかない 😱

# ✅ Enumならタむポした瞬間に゚ディタが赀線を匕いおくれる
if user.role == UserRole.ADIMN:  # 即座に゚ラヌずわかる 🎯

文字列をそのたた䜿うず "admin" を "admn" ず曞き間違えおも
プログラムが動いおしたい、バグの発芋が遅れたす。
UserRole.ADMIN のように曞けば゚ディタが
「そんなメンバヌはない」ず即座に教えおくれたす。


7. 🎯 たずめ

良いコメント vs 悪いコメント

✅ 良いコメント ❌ 悪いコメント
内容 「なぜ」そうしおいるか 「䜕を」しおいるかコヌドの翻蚳
鮮床 コヌドず䞀緒に曎新される 叀くなっお嘘を぀く
量 必芁なずころだけ 自明なこずにも曞く
コヌド コヌドが語る郚分はコメントなし コメントアりトされたコヌドが残る

docstringのポむント

項目 ポむント
📝 1行サマリヌ 関数が䜕をするか1文で簡朔に
📋 Args 匕数の意味・制玄を曞く
🔄 Returns 戻り倀が䜕を意味するか曞く
⚠ Raises 発生しうる䟋倖を曞く

マゞックナンバヌの察凊法

察象 察凊法
数倀 意味のある名前の定数に眮き換える
文字列 定数たたはEnumにたずめる
耇数の関連する倀 Enumクラスにたずめる

コメントの黄金ルヌル
① コヌドで「䜕を」䌝え、コメントで「なぜ」を䌝える
② コヌドを倉えたらコメントも倉える
③ 迷ったら「コメントなしでも読めるコヌド」を目指す

次回は ゚ラヌハンドリング を解説したす
䟋倖凊理の基本・゚ラヌメッセヌゞの曞き方・
防埡的プログラミングの考え方を孊びたす🌟

💬 質問や感想があれば、コメント欄でお気軜にどうぞ!
👍 圹に立ったら、いいね&ストックをお願いしたす!
🎓 ここたで読んでくださっお、本圓にありがずうございたした!


🔗 シリヌズ蚘事

  • 【第䞀回】コヌドの基本構造
  • 【第二回】呜名芏則
  • 【第䞉回】コヌドの蚭蚈原則
  • 【第四回】コメント・ドキュメントこの蚘事
  • 【第五回】゚ラヌハンドリング近日公開
  • 【第六回】テスト・ファむル構造・バヌゞョン管理近日公開
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?