はじめに

キャスレーコンサルティングの法島と申します。

現在の業務では、主にJavaを用いた開発を行っております。

今回は、良いコードを書くということをテーマに、話題の「リーダブルコード」を読んで
 ★ためになったなと思うこと
 ★知ればすぐに変えられるポイント
を、書こうと思います。

注意

  • 言語の制約は設けてはいませんが、筆者がJavaエンジニアのため例題等はJavaで記載しています。
  • 「必ずこうしなければならない」「絶対にこうすることが正しい」というものではございません。
  • プロジェクト内でのコーディング規約を考慮した上で、参考にしていただけますと幸いです。

リーダブルコードとは

リーダブルコードとは、O’REILLY発行の本で、“エンジニアが読むべき本”と検索すると必ずヒットするくらい著名な本です。

主に「良いコードを書く」をテーマに

  1. 「良いコードと悪いコードの例」
  2. 「良いコードを書くためのポイント」
  3. 「そのコードがなぜ読みやすいか」

が記述されていて、とてもわかりやすく、納得させられる内容ばかりです。


https://www.oreilly.co.jp/books/9784873115658/

良いコードとは具体的に何か?

良いコードってどういうもの?と聞かれた時に

  • コードが少ない
  • 無駄なコードがない

などの回答がよく挙げられると思います。

では、以下のコードはどちらの方が良いコードでしょうか?

例 1-1
  if (score >= 60) {
    return "合格";
  } else {
    return "不合格";
  }
 
例 1-2
  return score >= 60 ? "合格" : "不合格";
 

60を超える場合は「合格」とし、それ以外は「不合格」を返却する処理です。
結果はどちらも同じになります。
この場合は、if文で制御するよりも三項演算子で判断させた方が簡潔に見えます。

しかし、こちらのパターンが増えた場合はどうでしょうか?

例 2-1
  if (score >= 60) {
    return "合格";
  } else if (score >= 30) {
    return "追加課題";
  } else {
    return "不合格";
  }
 
例 2-2
  return score >= 60 ? "合格" : score >= 30 ? "追加課題" : "不合格";
 

今度は「60点未満30点以上の場合は追加課題」というパターンが追加されました。
この場合、三項演算子よりもif文の方が理解しやすいのではないでしょうか?

上記のようなパターンはかなり極端ですが、コードの量を減らすことが必ずしも良いコードということではないとわかります。

リーダブルコードでは、コードの読みやすさの定義を以下としています。

他の人が処理を最短時間で理解できるコード

初めて読んだ時は、ぐうの音も出ませんでした。

ソースコードは、誰が読むかわかりません。
プロジェクトを離れた後、不具合や仕様変更があれば、引き継いだ人がそのコードを読みます。
その人が最短時間で理解できるコードを書くことは、非常に大事なことだと私は思います。

意識すること

では、実際に「他の人が処理を最短時間で理解できるコード」を書くためにどこを意識したり、気をつけたら良いのでしょうか?

1.その名前は意味が通じるのか

名前が抽象的。
よくある事です。

データベースからデータを取得するというメソッドに対し、getDataという命名したとします。

このメソッド名は、非常に曖昧です。
一覧情報のように複数件取得するのか?
それとも、データの更新用に一件のみ取得するのか?
そもそも何のデータを取得するかも解りません。

「名は体を表す」と言います。
名前が曖昧だとそのメソッドや変数が何の役割を持っているか解らないので、そのメソッドの処理をきちんと確認するという無駄な時間を使うことになります。
また同様に、名前以上の役割を与えてしまうことも良くないので気をつけましょう。

命名した変数名やメソッド名を省略する時がありますが、こちらも同様に他の人がわかる場合(省略したものが一般的に使われる)は省略することも良いと思います。

 例. configuration → config, conf
     delete        → del 
     to            → 2
     for           → 4   等
 

また、真偽値の命名はis~,has~,can~,should~などを使うようにしましょう。

2.チームで書き方を統一する

一番わかりやすい例はマジックナンバーです。

値によって区別したいときに、自分で値を定義して
「1だったら…、2だったら…」
という制御をかけてしまうやり方です。

マジックナンバーを使うと、その意味をコメントに残さないと
「どのような制御を行なっているのか?」
が解りません。

このような場合は、Enum(列挙型) で定義しましょう。
Enumを使うことによって、仕様変更にも強くなりますし、同じチームの人も見ただけで解ります。

他の人と書き方を統一することで、初めて見るコードでも処理の流れが同じになり、読みやすくなります。

規約が厳密に定められていない場合は、変数定義、データのセットなど似たような役割を段落で分け、空行を入れることでコードの可読性を上げることができると思います。

また、インデントの縦軸を意識して、しっかり揃えることを心がけましょう。

例1
  public static Map<Long, Integer> test() {

    Map<Long, Integer> studentTestAve = new HashMap<Long, Integer>();

    //                           生徒ID               国, 数, 英, 理, 社
    studentTestAve.put(Long.valueOf( 1), getAverage( 55, 60, 80, 45, 90));
    studentTestAve.put(Long.valueOf( 7), getAverage( 80, 77, 55, 16, 34));
    studentTestAve.put(Long.valueOf(12), getAverage( 85, 70, 90, 26, 75));
    studentTestAve.put(Long.valueOf(16), getAverage( 10,  1, 65, 27, 30));
    studentTestAve.put(Long.valueOf(25), getAverage(100, 60, 80, 45, 90));

    return studentTestAve;	
  }
  
  public static Integer getAverage(int japanese, int math, int english, int science, int social) {
    return (japanese + math + english + science + social) / 5;
  }
 

3.本当に必要なコメントを書く

意味のないコメントは避けましょう。
せっかくコードを綺麗に書いても、コメントだらけのコードは可読性を下げる要因になります。

「自分がやりたいことが書かれていないコメント」
「処理の仕組みを説明しているコメント」
は良くないとされています。

では、なぜ良くないのでしょうか?

理由は、処理結果が正しいのか判断できないためです。

作成者が「どのように考えて処理を作ったのか」理解できれば、
・ロジックが間違っているか?
・やりたい事が違うか?
が判断できます。

これは、共通処理などで不特定多数の人が扱う場合は特に重要です。

共通処理ではなくても、「自分以外の人を意識する」は大前提です。
日頃から心がけましょう。

ポイントは、簡潔に書くことです。
式を使ったり、例を使っても良いでしょう。

また、コメントには典型的な意味を持たせる記法があります。

  • TODO: 着手予定
  • FIXME:不具合があるコード
  • HACK:あまり好まれないコード
  • XXX :大きな問題があるコード

その他にもMarkDown記法を使用したり、プロジェクト内でコメントのルールを定めることで、さらに可読性の高いコードになると思います。

4.if文をきれいに使う

if文のロジック周りでコードが汚くなるパターンは、
・制御文が複雑になっている
・ネスト(入れ子構造)になっている
という場合が多いです。

ネストは、可読性を著しく低下させます。

そのため、なるべくネストは浅くすることを意識しましょう。
ネストを止めたい場合は、全体をみて、最も単純な制御の物から処理をして返却しましょう。

例1
  if (a == 1) {
    if (b == 2) {
      // 処理1
    } else {
      // 処理2
    }
  }
 
例1の対策
  if (a == 1 && b == 2) {
    // 処理1
  } else if (a == 1 && b != 2) {
    // 処理2
  }
 
例2
  if (a == id) {
    if (b != 2) {
      // return 独自の処理1
    }
  } else {
    // return 独自の処理2
  }
  return // 残りの処理
 
例2の対策
  if (a != id) {
    // return 独自の処理2の結果
  }
  if (b != 2) {
    // return 独自の処理1の結果
  }
  return // 残りの処理
 

終わりに

いかがだったでしょうか?

今回は、リーダブルコードの中から「表面上の改善」を重点的に紹介させていただきました。
しかし、これはリーダブルコードに書かれている内容のごく一部でしかありません。
他にも非常に役に立つ内容が書かれていますので、興味を持たれた方はぜひ読んでみてください。

「良いコードを書くこと」は、簡単そうに見えますが意外と難しいものです。
しかし、日頃から意識して取り組むことで身につくと思います。
良いコードを書くことが当たり前になるように、習慣化して行きましょう。

以上です。
ここまで読んでいただき、ありがとうございました。

法島
CSVIT事業部 法島