契約による設計の部分的な実施のアイデアについて、いくつかの意見を聞きたいと思います。目標は、外部ライブラリを必要とせずに、ライトバージョンのコントラクト(不変条件と事後条件のみ)を提供しない言語に追加することです。
私の例はJavaで書かれていますが、このアイデアは多くのオブジェクト指向言語に適していると思います。
次のようなクラスがあります。
class myClass{
type1 field1;
type2 field2;
public myClass(type1 param1){
//do something
}
public type3 method1(type1 param1, type3 param2){
if (paramsAreNotOk()){
throw new IllegalArgumentException();
}
// do a lot of things
return //do something
}
}
上記のコードを次のように拡張します。
class myClass{
type1 field1;
type2 field2;
public myClass(type1 param1){
//do something
assert invariant();
}
public type3 method1(final type1 param1, final type3 param2){
assert invariant();
myClass old;
assert ((old = this.clone()) != null)
if (paramsAreNotOk()){
throw new IllegalArgumentException();
}
//do a lot of things
type3 res = //do something
assert method1_post(old, param1, param2, res);
assert invariant();
return res;
}
protected boolean invariant(){
// states something about myClass and return a boolean
// OR
// uses some assertions on some helping methods
}
protected boolean method1_post(myClass old, type1 param1, type3 param2, type3 res){
// states something about res and about the modifications made on old
// OR
// uses some assertions on some helping methods
}
}
このアプローチの制限:
-前提条件はありません。
-コントラクトは継承されません(ただし、不変条件と事後条件は保護されており、サブクラスで再利用できることに注意してください)。
-不変条件と事後条件がオブジェクトの状態を変更しないというチェックはありません。したがって、副作用のリスクがあります。
-契約は明確な方法で私たちの文書の一部ではありません。
-すべてのクラスを複製可能にする必要があります。
さて、いくつかの質問:
-この方法はパフォーマンスに何らかの影響を及ぼしますか?アサーションが無効になっている場合、古いローカル変数とresローカル変数でさえJITコンパイラによって削除されるということですか?
-このアプローチの欠点はありますか?なぜあなたはあなたのクラスでこれを使わないのですか?
-改善を提案できますか?
読んでいただきありがとうございます。