AspectJを使用してDbCを実践する時には、いくつか注意しなければならない点があります。それは主にAspectJがDbCに特化したツールでなく、「何でも出来てしまう」ために起きる現象です。
チェック対象オブジェクトはコントラクトがWeavingされていようといまいと、完全に同じように動作する必要がありますが、AspectJのを間違って使うと、この原則をいとも簡単に破壊することが出来てしまうのです。以下に注意点を述べます。
1.対象オブジェクトの状態を変更しないこと
事前条件/事後条件のチェックの際に、呼び出すチェック対象オブジェクトのメソッドは、対象オブジェクトの状態を変更してはいけません。そうしないと、コントラクト自体がオブジェクトの振舞に影響を与えてしまいます。
一般にDbCを適用する際には、メソッドを「コマンド」と「クエリ」に分けて考えると良いとされています。「コマンド」はオブジェクトの状態に影響を与える何らかの処理を実行するメソッドです。
「クエリ」はオブジェクトの状態を取得するメソッドで、それ自体がオブジェクトの状態を変更することはありません。平たくいうとgetterですね。DbCでは基本的に「コマンド」に対してコントラクトを定義します。そのコントラクト内で呼び出すメソッドは「クエリ」で無ければなりません。
クラスを設計する際に最初からメソッドを「コマンド」と「クエリ」に分けて考えておくと良いでしょう。
このあたりの考え方はDesign by Contract By Exampleという本に詳しく解説されています。DbCの基本が豊富な例題を用いて分かりやすく説明されており、おすすめの一冊です。
2.チェック対象メソッドの振舞を変更しないこと
コントラクト記述の際にはaroundアドバイスを多用しますが、aroundアドバイス内では元のメソッドの振舞を好きな様に変更できてしまうので注意が必要です。具体的には
1. proceedの戻り値をきちんと返却しているか?自分で勝手な戻り値を返していないか?
2. 例外が発生した場合、そのままスローしているか?握りつぶしたり、自分で勝手な例外を投げたりしていないか?
といった点に気を付ける必要があります。
以上の様な注意点の他にもいくつかのTipsや課題が明らかになりつつあります。それらに関しても適宜紹介して行きたいと思います。
チェック対象オブジェクトはコントラクトがWeavingされていようといまいと、完全に同じように動作する必要がありますが、AspectJのを間違って使うと、この原則をいとも簡単に破壊することが出来てしまうのです。以下に注意点を述べます。
1.対象オブジェクトの状態を変更しないこと
事前条件/事後条件のチェックの際に、呼び出すチェック対象オブジェクトのメソッドは、対象オブジェクトの状態を変更してはいけません。そうしないと、コントラクト自体がオブジェクトの振舞に影響を与えてしまいます。
一般にDbCを適用する際には、メソッドを「コマンド」と「クエリ」に分けて考えると良いとされています。「コマンド」はオブジェクトの状態に影響を与える何らかの処理を実行するメソッドです。
「クエリ」はオブジェクトの状態を取得するメソッドで、それ自体がオブジェクトの状態を変更することはありません。平たくいうとgetterですね。DbCでは基本的に「コマンド」に対してコントラクトを定義します。そのコントラクト内で呼び出すメソッドは「クエリ」で無ければなりません。
クラスを設計する際に最初からメソッドを「コマンド」と「クエリ」に分けて考えておくと良いでしょう。
このあたりの考え方はDesign by Contract By Exampleという本に詳しく解説されています。DbCの基本が豊富な例題を用いて分かりやすく説明されており、おすすめの一冊です。
2.チェック対象メソッドの振舞を変更しないこと
コントラクト記述の際にはaroundアドバイスを多用しますが、aroundアドバイス内では元のメソッドの振舞を好きな様に変更できてしまうので注意が必要です。具体的には
1. proceedの戻り値をきちんと返却しているか?自分で勝手な戻り値を返していないか?
2. 例外が発生した場合、そのままスローしているか?握りつぶしたり、自分で勝手な例外を投げたりしていないか?
といった点に気を付ける必要があります。
以上の様な注意点の他にもいくつかのTipsや課題が明らかになりつつあります。それらに関しても適宜紹介して行きたいと思います。
http://www-106.ibm.com/developerworks/library/j-ceaop/index.html?ca=drs-j3004
どうやら,
①Contract自体は通常のJavaクラス(ContractManagerインタフェースを持つ)として記述する(checkPreConditions()やcheckInvariants()メソッドなどを持つ)
②Abstractなアスペクト(AbstractContract)で条件チェックの①のメソッドを呼び出すようになっている
③②を実装するアスペクトで,Weavingする対象(pointcut)を定義したり,Contractを記述した①のインスタンスを返却するロジックを書く
となっているようです(記事読んでもらった方が分かると思います^^;).
pointcutの情報と,Contractの情報が2つのファイルに分かれてしまうことが問題なければ,まぁまぁ良いアイデアだとは思いますね.
ただ、メソッド毎にコントラクトとアスペクトを作成しなくてはならないのはあまりにも煩雑かな、と感じます。
そこを工夫して何とか出来ればかなり良いアプローチになりそうです。