Index: [Article Count Order] [Thread]

Date:  Tue, 26 Dec 2000 16:18:38 +0900
From:  Kenji Hiranabe <hiranabe@....jp>
Subject:  [XP-jp:01418] Re: assertion in Java
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <20001226161306Q.hiranabe@....jp>
In-Reply-To:  Your message of "Tue, 26 Dec 2000 15:28:38 +0900"	<3a483a09.6863%Morisue_Yoshihiko@....jp>
References:  <3a483a09.6863%Morisue_Yoshihiko@....jp>
Posted:  Tue, 26 Dec 2000 16:13:06 +0900
X-Mail-Count: 01418


平鍋です.

On Tue, 26 Dec 2000 15:28:38 +0900,
森末 吉彦 <Morisue_Yoshihiko@....jp> said:

 > 具体的なメリットがよくわからないのですが、assertionが使えば
 > たとえばどんなシチュエーションで楽になるのでしょうか?

DbC(Design by Contract) と呼ばれる設計手法があります.(See 
オブジェクト指向入門 by Bertrand Meyer)

メソッドの呼び出しを,呼び出し側と呼ばれる側の契約と捉えま
す.メソッドの責任は,呼び出し側が事前条件を満たせば,事後条
件を満たす.というものです.それぞれの条件は,それぞれメソッ
ドの開始前および終了後の assert で書くことができます.

class IntStack {
int itemCount;
int item[];
//...

public int pop() {
   assert(0 < itemCount);  // 事前条件
   // pop
}

public void push(int value) {
   // push
   assert(!this.isEmpty());      // 事後条件
   assert(this.contains(value)); // 事後条件
}

こうすることで,

1) ドキュメントより信頼できるメソッドの仕様を記述できます.
2) 不具合を切り分けることができます.(事前条件に引っかかれば
呼び出し側の契約不履行,事後条件に引っかかればメソッドの契約
不履行)

言語によっては他にも,継承のセマンティクスの強化(Liskov 則の
ランタイムチェック),synchronization (事前条件不成立ならブ
ロック),ドキュメントへの反映などなど,に利用されます.

さて,ここまでが前置き.
以下,今回の仕様追加により,楽になった部分を.

1つめ.

Java には,assert が言語に括り付けられていなかったため,これ
まで,Assert クラスを作って,

    Assert.assert(condition);

とか,UnitTest などでは,TestCase extends Assert, 
MyTestCase extends TestCase などとして,テストケース側に
assert を書いていました.

こういう Assert クラスを作成する手間がなくなる.

2つ目は,パフォーマンス.

class Assert {
   private boolean debug = on;
   static void assert(condition) {
       if (on && !condition)
           throw new Error();
   }
}

という具合に書いた場合,debug = false に設定しても,呼び出し
側のコードにパフォーマンスの負担ががかかります.できれば,
C 言語の #ifdef debug みたいにしたい.すなわち,

  pop() {
    Assert.assert(...);
    // ...
  }

は,debug の on/off に関わらず static method 呼び出しのペナ
ルティを負っていました.これが,assertが,構文糖として提供さ
れるため,

  pop() {
    if ($assertionEnabled) {
         // Assertion の thow
    }
  }

と展開され,コンパイラによってコンパイル時に assert をすっぱ
りバイトコードから消せます.

# There's no harm in asking ;-)

以上