はじめに
エンジニア歴10年ではじめて「リーダブルコード」を読みました。(恥ずかしながら)
リーダブルコードを読んでいく中で、実際の現場でこれは使えると思った箇所や、コードレビューで活用できると思った箇所を、私なりにまとめてみました。
この記事の対象者
- リーダブルコードの要点を5分で知りたい人
- 自己流でコードを書いてきた人
この記事でやらないこと
- 全ての章は書いていません
実際に使えると思った箇所や私が言語化できる部分をまとめたものになるので、全ての章を記載していません
第1部 表面上の改善
4章 美しさ
美しいコードは読み手を意識した構造
読みやすいコードっていいですよね!パッと見てすぐに理解できるコードは、チーム開発でも大活躍です。そのためには一貫性と視覚的な整列が重要です。
-
一貫性のある簡潔な改行位置
同じ目的や処理を行うコードブロックは、類似した「シルエット」を持たせます。
全体の構造が視覚的に統一されるので、理解しやすくなります。// 良い例: シルエットが揃っている if (user.isActive()) { processActiveUser(); } else { processInactiveUser(); } if (order.isPaid()) { shipOrder(); } else { cancelOrder(); }
// 悪い例: シルエットが揃っていない if (user.isActive()) { processActiveUser(); } else { processInactiveUser(); } if (order.isPaid()) shipOrder(); else cancelOrder();
- 縦の線をまっすぐにする
-
変数や値の代入を「整列」することで視覚的な把握が容易になります
-
定義やリストの項目を並べる際に効果的
// 悪い例: 整列されていない int maxUsers = 100; int currentUsers = 50; int remaining = maxUsers - currentUsers;
// 良い例: 整列されている(変数を揃えることで視覚的にわかりやすい) int maxUsers = 100; int currentUsers = 50; int remaining = maxUsers - currentUsers;
-
5章 コメントすべきことを知る
コメントするべきでは「ない」こと
コメントは開発者にとって「未来の自分」や「他のメンバー」へのメッセージです。ただし、以下のようなコメントは避けたほうが無難です。むしろ、書かない方がスッキリします!
- すぐにわかることを説明するコメント
- 足し算をしているだけのコードに「ここで足し算をする」と書いても、蛇足ですよね
- 関数名や引数をそのまま文章形式にしたコメント
- 良い名前がついていれば、そのまま意図が伝わります。無理にコメントを足すより、名前の改善を優先しましょう
- わかりにくい関数名を補うコメント
- コメントで補うより、関数名を「これだ!」と思えるくらい意味のあるものにする方が効果的です
例: 書かないほうが良いコメント
// 2つの数字を足し算する関数
function addNumbers(numA,NumB){
//ここで2つの数字を足す
return numA + NumB
}
このコメント、正直「見ればわかる」ですよね。これならむしろ、コメントなしでスッキリさせたほうが良いです。
コメントに書くべきこと – 自分の考えを記録する
コメントを書くべきタイミングは、コードだけでは伝えきれない 「意図」や「背景」 を記録したいときです。読んだ人が「なぜそうしたのか」を理解できるようにするのがポイント!
-
意図:なぜその実装を選んだのか?
- 「このアルゴリズムを採用した理由」や「なぜこの値を固定にしたのか」など
-
背景:トレードオフや制約条件
- 「パフォーマンスを優先してこう書いた」や「このAPIは現在の要件でしか使えない」
-
将来的な課題や改善点:未来のために備える。
- 「次のバージョンでここをリファクタリングする必要あり」や「ここは仮実装、要確認」
6章 コメントは正確で簡潔に
あいまいな代名詞はNG!
コメントを書くとき、あいまいな言葉は読んだ人を迷子にしてしまうことがあります。特に「その」「これ」みたいな代名詞は要注意!指している対象が明確でないと、かえって混乱を招きます。
悪い例: 読む人を悩ませるコメント
// データをキャッシュに入れる。ただし、先にそのサイズをチェックする
「そのサイズ」って、どれのサイズ?
データのサイズ?キャッシュのサイズ?これだと読む人はコードをじっくり確認しないとわかりませんよね。せっかくのコメントが手間を増やしてしまっています。
良い例: 具体的で迷いのないコメント
// データをキャッシュに入れる。ただし、先にデータのサイズをチェックする
「データのサイズ」と明確に書いてあれば、読む人は迷いません!コメントが具体的だと、意図が一目で伝わります。
第2部 ループとロジックの単純化
7章 制御フローを読みやすくする
コードの流れは読みやすさ命!
制御フローを工夫するだけで、コードの読みやすさが格段にアップします!
以下のポイントを押さえて、保守性もバッチリなコードを書いていきましょう!
条件式の引数の並び順
調査対象は左、比較対象は右に置く!
条件式を書くときは、左側に「変化するもの(調査対象)」、右側に「変化しないもの(比較対象)」を配置するのが鉄則です。この書き方だと、自然な言葉の流れで読みやすくなります。
// 悪い例
if(18 <= age) {
// 読みにくい
}
// いい例
if (age >= 18) {
System.out.println("You are an adult.");
}
if/elseブロックの並び順
-
否定系より肯定系を使う!
-
if (!debug)
よりもif (debug)
の方が直感的でわかりやすいです。否定系は読むのにワンクッション必要なので、できるだけ避けましょう。if (debug) { log("Debug mode is active."); } else { log("Debug mode is inactive."); }
-
-
単純な条件を先に書く!
シンプルな条件を先に書くことで、コードの意図が伝わりやすくなります。複雑な条件は後回しにして、徐々に深掘りする形にしましょう
if (isActive) { processActiveUser(); } else if (isAdmin) { processAdminUser(); } else { processGuestUser(); }
-
立つ条件を先に書く!
-
読者(未来の自分や他の開発者)が「これは重要だな」と思う条件を最初に書くと、コードの意図がよりクリアになります
if (isCriticalError) { handleCriticalError(); } else if (isWarning) { handleWarning(); } else { handleNormalOperation(); }
-
8章 巨大な式を分割する
大きなコードは小さく分けると見やすい!
クラスやメソッドが複雑になりすぎると、理解するのが大変ですよね。特に、一つのメソッドで「全部やろう」とすると、どんどん読みづらい「大きな塊」になってしまいます。
そんなときは 「飲み込みやすいサイズに分割」 するのがコツです!
要約変数でコードをスッキリ
複雑な式や条件式を、そのまま書くと読みにくくなりがちです。
そこで「要約変数」を使うと、一気にスッキリさせることができます。
if (request.user.id == document.owner_id) {
// ユーザーはこの文章を編集できる
}
if (request.user.id != document.owner_id) {
// 文章読み取り専用
}
これでも動きますが、「文章編集権限を持っているか」という意図がパッと見て分かりづらいですね。
要約変数を使って改善
private final boolean userOwsDocument = (request.user.id == document.owner_id)
if (userOwsDocument) {
// ユーザーはこの文章を編集できる
}
if (!userOwsDocument) {
// 文章読み取り専用
}
変数名 userOwnsDocument を追加するだけで、コードの意図が明確になりました!
メソッドの冒頭に定義しておけば、「この関数で大事な概念はこれだな」とすぐに理解できます。
ド・モルガンの法則で論理式をわかりやすく
論理式が複雑すぎて「うーん、これ何だっけ?」となることありませんか?
そんなときに使えるのが ド・モルガンの法則 です!
簡単に言うと、「not を分配して and/or を反転する」ルールです。
例: 曖昧なコード
if (!condition1 || !condition2) {
// 条件1がtureであるか、または条件2がtrueである場合にtrueとなる
}
これだと読むたびに「えーと…」ってなりそうですよね。
例: ド・モルガンの法則で改善
if (!(condition1 && condition2)) {
// 条件1と条件2の両方がtrueでない場合にtrueとなる
}
not を外側に出して && に変えることで、意図がわかりやすくなります。
「どちらか1つがfalse」より「両方がtrueでない」を意識した方が自然な場合に便利です!
第3部 コードの再構成
10章 無関係の下位問題を抽出する
再利用できるコードは切り出そう
コードを書くとき、「これ、他でも使えそうだな」と感じたことはありませんか?
そんなときは、プロジェクト特有の部分を汎用コードとして分離してみましょう。
これを「無関係の下位問題を抽出する」といいます。
例:特定のデータ構造を操作するロジックを、汎用的なライブラリやヘルパー関数にすることで、次のプロジェクトでもサクッと再利用できます!
抽出の判断基準
- 再利用できる可能性が高いコードは切り出す価値アリ
- ただし、他の部分から再利用できる見込みがないコードは無理に切り分けない方が良いです
11 章 一度に一つのタスクを処理する
関数に何役も押し付けないで!
1つの関数があれこれ詰め込みすぎていると、読む側が混乱してしまいます。関数は 「一つのタスクだけを処理する」 のが理想です。
-
タスクをリストアップして分割
「なんかこの関数、読みにくいな」と思ったら、まずその中で行われているタスクをリストアップしましょう
複数のタスクが見つかったら、それぞれを別の関数やクラスに分けるのがおすすめです! -
説明できるコードがベスト
書いたコードが「何をしているか」を簡単な言葉で説明できればOK!
もし説明に詰まるようなら、その部分は複雑すぎる可能性があります。シンプル is ベスト を心がけましょう
12章 コードに思いを込める
「未来の仲間に伝える気持ちで書こう!」
コードを書くとき、自分より知識の少ない人でも理解できる言葉で説明することを意識しましょう。たとえば、複雑なアルゴリズムや設計の意図も、平易な言葉で表現することでグッと分かりやすくなります。
-
プログラムを言葉にする
コードの内容を説明する際に、スラスラと言葉にできることが理想です。
もし言葉に詰まる場合は、実装や設計がまだ曖昧であるサインかもしれません。
そのタイミングで見直すと、コードがさらに洗練されますよ! -
意図を明確にする
曖昧な設計や処理は避け、誰が見ても「あ、こういう意図なんだな」と伝わるコードを書くのが大事です
13章 短いコードを書く
標準ライブラリは宝箱!
標準ライブラリには、便利な関数やモジュールがたくさん詰まっています。
これを活用することで、余計な手作業を減らし、コードを短くシンプルにできます。
- 標準ライブラリを見直そう
定期的にライブラリの関数やモジュールを見直す習慣をつけましょう。
「え、こんな便利なものあったんだ!」と気づけることも多いですよ!
例:標準ライブラリを使わない
List<String> upperCaseNames = new ArrayList<>();
for (String name : names) {
upperCaseNames.add(name.toUpperCase());
}
例:標準ライブラリを使う
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
さいごに
リーダブルコードを読んでみた感想としては、
書いてある内容は理解はできる。しかし、自分で言語化できていない部分が多々あったことを痛感した。
こうしてアウトプットをすることで、腑に落ちていない部分が分かったので、定期的に読み直しをしたい。
今後の展望
リーダブルコードを活用した開発をどのように現場に落とし込むべきか。シンプルに開発者全員読んでくださいという方針ではなく、コードを書く際の必要順序リストのようなものを作成し、効果があるのか検証をしたい。