【发布时间】:2011-10-24 06:01:33
【问题描述】:
我想就合同设计的部分实施的想法获得一些意见。 目标是在不需要外部库的情况下向不提供轻量级合约(仅不变量和后置条件)的语言添加。
我的示例是用 Java 编写的,但我认为这个想法适用于许多 OO 语言。
我们有一个这样的类:
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
}
}
这种方法的局限性:
- 没有先决条件。
- 合同不是继承的(但请注意,不变量和后置条件受到保护,可以被子类重用)。
- 没有检查不变量和后置条件不会修改我们对象的状态,因此存在副作用的风险。
- 合同并没有明确地包含在我们的文档中。
- 我们需要让每个类都可以克隆。
现在,一些问题:
- 这种方法对表演有任何影响吗?我的意思是如果禁用断言,JIT 编译器甚至会删除 old 和 res 局部变量?
- 你觉得这种方法有什么缺点吗?为什么不在课堂上使用它?
- 你能提出任何改进的建议吗?
感谢您的阅读和您的意见。
【问题讨论】:
标签: java language-agnostic assertions design-by-contract