2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【言語不問】脱・初心者からベテランの復習まで。「リーダブルコード」実践ベストプラクティス

Posted at

エンジニアとして働いていると、「コードは書く時間よりも読まれる時間の方が圧倒的に長い」という事実に直面します。それは他人が書いたコードかもしれないし、3ヶ月前の(すっかり記憶から消えた)自分が書いたコードかもしれません。この記事では、名著『リーダブルコード』の考え方をベースに、明日からすぐに実践できる「良いコード」を書くためのテクニックをまとめました。新人エンジニアの方は基礎力アップとして、ベテランエンジニアの方はレビュー時の観点や自身の復習としてご活用ください。

書籍リンク

はじめに:「良いコード」とは何か?

「良いコード」の定義はプロジェクトやチームによって異なりますが、最も普遍的で重要な指標はこれです。

「理解するのにかかる時間が短いコード」

高性能なアルゴリズムや短い行数で書かれたコードよりも、「他の人が読んだ時に、スッと頭に入ってくるコード」こそが、チーム開発において最も価値があります。

1. 命名:名前こそが最大のドキュメント

プログラミングにおいて最も悩み、かつ重要なのが「命名」です。変数名や関数名が適切であれば、コメントすら不要になります。

🚫 具体性のない名前を避ける

tmp, data, info, ret のような汎用的な名前は避けましょう。「何が入っているか」を具体的にします。

悪い例:

def process(data):
    # dataが何なのか、何をするのか全くわからない
    ...

良い例:

def save_user_profile(user_profile):
    # ユーザープロフィールを保存するという意図が明確
    ...

📏 単位や状態を含める

数値やブール値には、単位や問いかけを含めると誤解を防げます。

  • 時間・単位: startstart_ms(ミリ秒), sizesize_mb(メガバイト)
  • 状態: flagis_valid, has_error, can_edit

💡 ベテラン向けTips:コンテキストを意識する

クラスのメンバ変数であれば、クラス名自体がコンテキストになるため、冗長な名前を避けることができます。User クラスの中に user_name プロパティは不要です。User.name で十分伝わります。

2. 制御フロー:脳のメモリを消費させない

ネスト(入れ子)が深いコードや、複雑な条件分岐は、読み手の「脳内メモリ」を消費させます。

🛡 ガード節(Early Return)を使う

条件分岐のネストを減らす最強の手段です。「例外的なケース」を先に関数の出口(return)へ誘導し、メインの処理をインデントなしで記述します。

悪い例(ネストが深い):

function sendEmail(user, message) {
  if (user != null) {
    if (user.hasEmail) {
      if (message != "") {
        // ここでやっと送信処理
        emailService.send(user.email, message);
      }
    }
  }
}

良い例(ガード節):

function sendEmail(user, message) {
  // 前提条件のチェック
  if (user == null) return;
  if (!user.hasEmail) return;
  if (message == "") return;

  // メインの処理(ネストがなくなり見やすい!)
  emailService.send(user.email, message);
}

🧠 ド・モルガンの法則で否定を整理する

「否定の否定」は理解に時間がかかります。肯定形を使いましょう。

  • if (!is_disable)if (is_enable)
  • if (!(file_exists && !is_protected))if (!file_exists || is_protected)

3. コメント:「What」ではなく「Why」を書く

「コードを見ればわかること」をコメントに書く必要はありません。コードだけでは表現しきれない**「意図」や「背景」**を書きましょう。

悪い例(コードの復唱):

# ユーザーIDで検索する
user = db.find(user_id)

# タイムアウトを1000にする
timeout = 1000

良い例(理由や背景):

# パフォーマンス上の理由で、キャッシュから先に検索する
user = cache.get(user_id)

# 外部APIの仕様により、最低1秒待機する必要があるため設定
timeout = 1000

💡 ベテラン向けTips:TODOコメントの活用

コードは常に完璧ではありません。「後で直す」「既知のバグがある」といった情報は、TODO:FIXME: を使って明示的に残し、負債を可視化しましょう。

4. 変数:スコープは小さく、寿命は短く

変数が参照できる範囲(スコープ)が広いと、どこで値が変更されたかを追うのが難しくなります。

  • グローバル変数は避ける: 依存関係がスパゲッティ化する元凶です。
  • 変数は使う直前で宣言する: コードの先頭でまとめて宣言するのではなく、使用する場所の近くで宣言します。
  • 再代入を避ける: 可能であれば const (JS) や final (Java) を使い、一度入れた値が変わらないことを保証すると、読み手は安心します。

5. 抽象化:マジックナンバーを撲滅する

コードの中に突然現れる 0, 1, 86400 などの数値を「マジックナンバー」と呼びます。これらは意図が不明瞭です。

悪い例:

# 突然の86400...これは何?
if (duration > 86400):
    ...

良い例(定数化):

SECONDS_IN_A_DAY = 86400

if (duration > SECONDS_IN_A_DAY):
    ...

定数に名前がついているだけで、コードの意味が劇的にわかりやすくなり、仕様変更(制限値の変更など)にも強くなります。

6. ベテランエンジニアへ:チームの文化を作る

ここまでは「個人のスキル」ですが、ベテランエンジニアには「チーム全体のコード品質」を底上げする役割が求められます。

🤖 ツールに任せられることは人間がやらない

インデントのズレやスペースの有無など、スタイルに関する指摘でレビュー時間を浪費するのは無駄です。Prettier (JS), Black (Python), gofmt などのフォーマッタを導入し、保存時に自動整形される仕組みを作りましょう。人間は「設計」や「ロジック」の議論に集中すべきです。

🏕 ボーイスカウトの規則「来た時よりも美しくして去る」

自分がコードを触ったついでに、少しだけ周辺のコードも綺麗にする習慣をチームに定着させましょう。大規模なリファクタリングは許可が出にくいですが、数行の修正なら日常的に行えます。

まとめ

良いコードを書くことは、**「未来の自分やチームメイトへの思いやり」**です。

  • 名前に情報を詰め込む
  • ガード節でネストを浅くする
  • コメントには「なぜ」を書く
  • 変数のスコープは最小限にする
  • 定数を使って意味を明快にする

これらを意識するだけで、あなたのコードは劇的に読みやすくなります。完璧を目指す必要はありません。まずは「昨日より少しだけ読みやすいコード」を目指してみましょう!

参考文献

Dustin Boswell, Trevor Foucher 著『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?