エンジニアとして働いていると、「コードは書く時間よりも読まれる時間の方が圧倒的に長い」という事実に直面します。それは他人が書いたコードかもしれないし、3ヶ月前の(すっかり記憶から消えた)自分が書いたコードかもしれません。この記事では、名著『リーダブルコード』の考え方をベースに、明日からすぐに実践できる「良いコード」を書くためのテクニックをまとめました。新人エンジニアの方は基礎力アップとして、ベテランエンジニアの方はレビュー時の観点や自身の復習としてご活用ください。
書籍リンク
はじめに:「良いコード」とは何か?
「良いコード」の定義はプロジェクトやチームによって異なりますが、最も普遍的で重要な指標はこれです。
「理解するのにかかる時間が短いコード」
高性能なアルゴリズムや短い行数で書かれたコードよりも、「他の人が読んだ時に、スッと頭に入ってくるコード」こそが、チーム開発において最も価値があります。
1. 命名:名前こそが最大のドキュメント
プログラミングにおいて最も悩み、かつ重要なのが「命名」です。変数名や関数名が適切であれば、コメントすら不要になります。
🚫 具体性のない名前を避ける
tmp, data, info, ret のような汎用的な名前は避けましょう。「何が入っているか」を具体的にします。
悪い例:
def process(data):
# dataが何なのか、何をするのか全くわからない
...
良い例:
def save_user_profile(user_profile):
# ユーザープロフィールを保存するという意図が明確
...
📏 単位や状態を含める
数値やブール値には、単位や問いかけを含めると誤解を防げます。
- 時間・単位:
start→start_ms(ミリ秒),size→size_mb(メガバイト) - 状態:
flag→is_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 著『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』