事前条件(Precondition)を使おう

Guiceのソースコードを読んでいて、至る所に事前条件をチェックしている部分があった。
たとえばAbstractModuleのconfigureメソッドは次にようになっている。

  public final synchronized void configure(Binder builder) {
    checkState(this.binder == null, "Re-entry is not allowed.");

    this.binder = checkNotNull(builder, "builder");
    try {
      configure();
    }
    finally {
      this.binder = null;
    }
  }

checkStateでメソッドを実行する前のメンバの状態をチェックし、checkNotNullで引数がnullで無いことをチェックしている。
もしチェックに失敗すると、第2引数をメッセージとして持つIllegalStateExceptionやNullPoがスローされる。

ちょっとの手間をかけるだけで頑健なプログラムを作るのに役に立つし、ソースコードを見る側にも「このメソッドが呼ばれたときにどういう状態になっているべきか」がわかりやすくなる。
次作るプログラムは事前条件をチェックするようにしてみよう。

なお、Guice3.0のPreconditionsクラスには次のチェックがある。実際のソースコードはこちら

  • checkArgument
    引数をチェックする。チェックに失敗するとIllegalArgumentException。
  • checkState
    メソッドを実行した際の、インスタンスの状態をチェックする。チェックに失敗するとIllegalStateException。
  • checkNotNull
    nullではないことをチェックする。checkNotNullメソッドの戻り値を使うことで、nullでないことを保証する。チェックに失敗するとNullPointerException。
  • checkContentsNotNull
    Iterableにnullが含まれていないことをチェックする。ArrayListなどはadd(null)を許容するため。チェックに失敗するとNullPointerException。
  • checkElementIndex
    要素のインデックスをチェックする。負のインデックスになっていないか、サイズを超えていないか。チェックに失敗するとIndexOutOfBoundsException。
  • checkPositionIndex
    ポジション(?)のインデックスをチェックする。checkElementIndexと違い、たとえば要素のサイズが5の時に、5のインデックスはOK。チェックに失敗するとIndexOutOfBoundsException。

Preconditionsクラスをコ(ry 参考にすれば、すぐに事前条件を使ってバグの少ないメンテナンス性の高いコードを書くことができるので、是非とも使ってみよう!

No Comments

Post a Comment

コメントを投稿するには、下の計算の答えを入力する必要があります。答えは半角数字で入力してください。 * Time limit is exhausted. Please reload the CAPTCHA.