今回はリーダブルコードの4章より「読みやすいコード」とするための「見た目、レイアウト」について触れていきます。
内容紹介
4章 美しさ
- 4章 美しさ
- 4.1 なぜ美しさが大切なのか?
- 4.2 一貫性のある簡潔な改行位置
- 4.3 メソッドを使った整列
- 4.4 縦の線をまっすぐに
- 4.5 一貫性と意味のある並び
- 4.6 宣言をブロックにまとめる
- 4.7 コードを「段落」に分割する
- 4.8 個人的な好みと一貫性
- 4.9 まとめ
4章ではコードを読みやすくするために、余白、配置、順序をどのように工夫するのが良いかを解説しています。
この読みやすさを考えるにあたり、まず最初に3つの原則を挙げています。
- 読み手が慣れているパターンと一貫性のあるレイアウトを使う。
- 似ているコードは似ているように見せる。
- 関連するコードをまとめてブロックにする。
「見た目」には個人の好みがあるため、全員が満足するものにはできません。しかし、この原則を用いることで大体の方が見やすいと感じる見た目にできます。
4.1, 4.2, 4.4 コードフォーマッタの活用
「4.1 なぜ美しさが大切なのか?」、「4.2 一貫性のある簡潔な改行位置」はインデント、改行位置の使い方を統一することで、視覚的に見やすくすることの大切さを述べています。この視覚的な見やすさについてはコードフォーマッタを活用しましょう。
インデントの深さや、文字数による改行位置の調整は人間が頑張るよりも、機械にお願いした方が楽なうえに正確です。
利用しているEditor、IDEでコード保存時に自動的にコードフォーマットを行う設定を導入しましょう。意識しなくても勝手に綺麗になる仕組みを作ってしまうのが良いです。
コードフォーマッタを使うと縦を揃えられなくない?
「4.4 縦の線をまっすぐに」では、コードを読みやすくするために、スペースを使って縦を揃える方法が紹介されています。しかし、コードフォーマッタを導入すると余分なスペースが自動的に削除されるため、スペースを使って縦を揃えることができません。
このような場合は、コードフォーマッタを一時的に無効化する機能があります!
Eclipseでコードフォーマッタを一時的に無効化する
以下はEclipseの設定になります。
「上部メニュー → ウィンドウ → 設定 → Java → コード・スタイル → フォーマッタ」を選択して右側に表示される「編集」ボタンクリック
左下の「off/on タグを使用可能にする」にチェックを付けます。これでコメントを利用して一時的にコードフォーマットを無効化することができます。
列挙体、JUnitのテストデータなど、関連するものが並ぶ箇所は縦を揃えたくなります。このような箇所にはコードフォーマッタの無効化を活用しましょう。
コードフォーマッタを一時的に無効化することでこんな感じに縦を揃えられます。
public enum RoleType { //@formatter:off //Enum名(DDL表示順, 日本語表示, 英語表示 GUEST (0, "一次利用", "Guest"), USER (1, "利用者", "User"), ADMIN (9, "管理者", "Administrator"); //@formatter:on /** ドロップダウンリストに表示する順番 */ private final int ddlOrder; /** 日本語表示 */ private final String nameJp; /** 英語表示 */ private final String nameEn; ... }
但し、この機能を乱用してしまうとコードフォーマッタの意味がなくなってしまいます。どのような箇所に利用するかルールをちゃんと決めて運用しましょう。
4.3 メソッドを使った整列
同じ処理を何度も実行している場合は、その処理をまとめたメソッドを作成して重複コードを減らしましょう。 重複コードをメソッドにまとめることでコードが簡潔になりますしDRY原則を順守できます。
但し、重複コードをメソッドにまとめたとき、メソッド名の命名で手を抜くと読みにくいコードになります。命名は非常に大事です!手を抜かないようにしましょう!
リーダブルコードの具体例
テストコードで同じようなアサート処理が繰り返されており読みにくいコードになっている。
// DBから略称に対応する正式名称を取得するメソッドのテスト assertEquals("Mr. Douglas Adams", expandFullName(dbConnection, "Doug Adams", error)); assertEquals("", error.getMessage()); assertEquals("", expandFullName(dbConnection, "No Such Guy", error)); assertEquals("no match found", error.getMessage()); assertEquals("", expandFullName(dbConnection, "John", error)); assertEquals("more then one result", error.getMessage());
何度も実行している処理をまとめてテスト用のヘルパーメソッドを作成することでテストコードが読みやすくなります。
// テスト用のヘルパーメソッド void checkFullName(String name, String expectedFullName, String expectedError) { String actualFullName = expandFullName(dbConnection, name, actualError); assertEquals(expectedFullName, actualFullName); assertEquals(expectedError, actualError.getMessage()); } // DBから略称に対応する正式名称を取得するメソッドのテスト checkFullName("Doug Adams", "Mr. Douglas Adams", ""); checkFullName("No Such Guy", "", "no match found"); checkFullName("John", "", "more then one result");
今後テストパターンを追加するとき、簡単に追加できるようになりました。
4.5, 4.6, 4.7 意味のある形でコードを並べる、まとめる
「4.5 一貫性と意味のある並び」「4.6 宣言をブロックにまとめる」「4.7 コードを「段落」に分割する」では、読みやすくするためにコードの並び順やまとめ方について解説しています。
ここで重要なことは「意味のある並び順」、「意味のあるまとまり」です。コードが行っていることをちゃんと理解した上で「意味のある」形で並べたり、まとめたりすることで、後からコードを読んだ人も意味が理解しやすくなります。
意味のある並び順
Web画面でお客さんに「住所、氏名、年齢、電話番号」を入力してもらった場合、そのリクエストを受け取ったサーバ側も同じように「住所、氏名、年齢、電話番号」の順番でリクエストから値を取得しましょう。
フロントの画面を見た人がバックエンドのコードを読んだときに読みやすいです。
受け取った値をバリデーションチェックするときも「住所、氏名、年齢、電話番号」の順番で行いましょう。
一貫性を持った意味のある並びとすることでコードが読みやすくなります。
意味のあるまとまり
ただ処理を羅列している状態は読みにくいです。意味のあるまとまりで「空行を入れる、コメントを入れる、メソッドにまとめる」などコードの中にも段落を作ることで読みやすくなります。
どのようにまとめたら良いのか分かりません!という方はまず「入力、処理、出力」に分けてみましょう。なぜなら、プログラムの構成要素は大きく分けるとこの三つになるからです。
- 入力:引数、リクエスト、ファイル、DBなど何らかの形で入力する
- 処理:入力されたデータを元に何らかの処理を行って処理結果を作成する
- 出力:処理結果を戻り値、レスポンス、ファイル、DBなど何らかの形で出力する。
殆どのプログラムはこの流れになります。なのでこの形でまとめると処理の流れが読みやすくなります。
逆に言うと、処理の途中で逐次データを読み込んで入力したり、処理の途中で結果が確定していないのに出力を行ったり(この場合、最終的に確定した値で出力を上書きしたりしていると非常に理解しにくい)、処理をまとめずに混ざっている状態だと後から読んだとき理解が難しくなります。
まとめ
本記事では、リーダブルコード4章の内容を解説しました。
一貫性のある統一された見た目とする際は、コードフォーマッタがとても役立ちます。
コードフォーマッタを導入しても一時的に無効化することが可能です。コードフォーマッタを導入したことでできなくなることは一切ありません。
見た目の整理整頓は機械がうまいことやってくれます。機械が得意なことは機械にお願いして人間は楽をしましょう!!