LoginSignup
0
0

More than 1 year has passed since last update.

読みやすいコードって?① - if条件を書くとき

Last updated at Posted at 2021-05-08

プログラミングをする際に良く耳にする「可読性」という言葉があります。
私はプログラミング未経験から縁があってIT企業に入社し今はSEとして働いていますが、
ほぼ独学で身につけたスキルのため、「可読性の高いコード」や「読みやすいコード」と言われても、正直どういうコードが読みやすいの?というのが分かりませんでした。

この記事では、具体的な例を挙げながら、なぜ読みやすいのか?なぜ読みにくいのか?について考えたいと思います。
「可読性ってどうやって考えたらいいの?」と思っている昔の私(今もですが・・)のような方の引き出しの一つに加えてもらえたら嬉しいです。

具体例

例えば、映画のチケット料金を計算するプログラムを書く時、
以下のようなクラスがあったと仮定します。

  • 上映映画クラス(MovieOnPlay)・・・チケットを計算する元になる上映時間等を含んだ映画のクラス。
  • 料金計算クラス(PriceCalculator)・・・上映映画を引数にとって、上映映画クラスの情報を元にチケット料金を計算する。
MovieOnPlay.java
/**
 * 上映映画クラス.
 */
class MovieOnPlay {
    /** 映画の名前. */
    private String name;
    /** 上映開始時間. */
    private LocalDateTime startTime;

    /** 上映開始時間getter. */
    public LocalDateTime getStartTime() {
        return thie.startTime;
    }

    // この下にgetter、setterが続く想定(今回の記事には関係ないので省略)
}
priceCalculatro.java
/**
 * チケット料金を計算する.
 * @param movie 上映映画
 * @return チケット料金
 */
public Integer calculate(MovieOnPlay movie) {

    LocalDateTime now = LocalDateTime.now();

    // 引数で受け取ったmovieがnullの場合と、
    // movieの上映開始時間がシステム日付(now)より後だった場合は
    // RuntimeExceptionを投げるコードをここに記述する

    // 料金計算ロジック
    calculatePrice(movie);
}

エラーチェックを行うコードを書くことを考えてみる

料金計算クラス(PriceCalculator)で、料金計算を行う前に以下のエラーチェックを行う場合を考えます。

  • 引数に受け取った上映映画クラスがnullだった場合はエラー
  • 料金計算しようとしている映画の上映開始時間が、現在の時間より前だった場合(すでに上映開始時間が過ぎている場合)はエラー

上記のチェックを行うコードを書く場合、以下の2つの書き方は同じ動きをします。

// 書き方の候補①
LocalDateTime now = LocalDateTime.now();
if( !(movie != null && movie.getStartTime().isBefore(now)) ) {
    throw new RuntimeException("正しい上映映画が選択されていません。")
}

// 料金計算ロジック
calculatePrice(movie);
// 書き方の候補②
LocalDateTime now = LocalDateTime.now();
if(movie == null || movie.getStartTime().isAfter(now)) {
    throw new RuntimeException("正しい上映映画が選択されていません。")
}

// 料金計算ロジック
calculatePrice(movie);

では、どちらが”可読性が高い”と言えるでしょうか?
実は可読性が高いのは①であると考えることができます。

なぜ①の方が可読性が高いと言えるのか?

エラーにならない条件から考えてみる

後から別の担当者がこのコードを見た場合、おそらく「どうしたらcalculate(movie)が実行されるのかな?」という観点で見ることが多いと思います。
RuntimeExceptionがスローされる条件より、calculate(movie)が実行される条件の方が、実際の業務においては重要だからです。

  • movieがnullではない
  • startTimeがnowより前である

上記の2つの条件を満たせば、ifブロックをスルーしてcalculatePrice(movie)を実行することができます。
逆に、”そうでない場合”はRuntimeExceptionをスローします。
それをそのままコードに落とし込んだのが①です。

// movieがnullではない
movie != null
// startTimeがnowより前である
movie.getStartTime().isBefore(now)
// ”そうでない場合”はRuntimeExceptionをスロー
if( !(movie != null && movie.getStartTime().isBefore(now)) ) {
    throw new RuntimeException("正しい上映映画が選択されていません。")
}

上記の!( ) をはずした「movie != null && movie.getStartTime().isBefore(now)」を満たしたものがcalculate(movie)を実行できます。

②をもう一度見てみる

②をのコードを「どうしたらcalculate(movie)が実行できるか?」という観点で見てみます。
if分の中のコードに”当てはまらない”条件であれば実行できるのですが、
「movie == null」 の逆はすぐわかるとしても、「movie.getStartTime().isAfter(now)」でない条件とは何か?を考えた時に、少し時間がかかるのではないでしょうか?

// 書き方の候補②
LocalDateTime now = LocalDateTime.now();
if(movie == null || movie.getStartTime().isAfter(now)) {
    throw new RuntimeException("正しい上映映画が選択されていません。")
}

// 料金計算ロジック
calculatePrice(movie);

そのため、①の方が可読性が高いと考えられます。

まとめ

今回はif文でエラーチェックを行う際の”読みやすさ”について考えてみました。
実際の業務では上記のようなケースはよくありますし、私も仕事をしていく中でif文に”当てはまらない”条件を考えるのに苦労したことは何度もあります。

プログラミングを勉強していく中で、こういった考え方でコードを書けば後々わかりやすいのか!と納得したうちの一つだったので記事にしてみました。

プログラミングは奥が深いので必ずしもこの書き方が100%正しいとは言えないのですが、こういった考え方を知っていくことで少しでも”読みやすい”コードを書けるようになりたいなと思います。

0
0
2

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