gpt4 book ai didi

java - 带有断言的契约(Contract)部分设计

转载 作者:行者123 更新时间:2023-11-29 03:58:11 24 4
gpt4 key购买 nike

我想就按契约(Contract)部分实现设计的想法征求一些意见。目标是在不需要外部库的情况下向不提供契约(Contract)的轻型版本(仅不变量和后置条件)添加语言。

我的示例是用 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
}
}

这种方法的局限性:
- 没有先决条件。
- 契约不被继承(但请注意,不变量和后置条件是 protected ,可以被子类重用)。
- 没有任何检查以确保不变条件和后置条件不会修改我们对象的状态,因此存在副作用的风险。
- 契约(Contract)显然不是我们文档的一部分。
- 我们需要使每个类都可克隆。

现在,一些问题:
- 这种方法是否会以任何方式损害表演?我的意思是,如果断言被禁用,即使是旧的和 res 局部变量也会被 JIT 编译器删除?
- 你认为这种方法有什么缺点吗?你为什么不在类里面使用它?
- 你能提出任何改进建议吗?

感谢您的阅读和意见。

最佳答案

这并不可怕,事实上,在您之前已经有其他人写过。例如,参见 Liskov/Guttag 的 Program Development in Java ,它采用您的方法进行不变检查,但将其称为 repOK() 而不是 invariant()。

在有限的应用程序中,它有点工作。但是,由于合约规范不必像实际代码那样担心那种“谁在调用谁”的问题,因此会产生很多问题。

  • 假设您有一些方法 F,它调用另一个方法 G。假设 F 在运行时破坏了表示不变量,但在它返回之前修复了一些东西。这是允许的,在某些情况下是必需的,但 G 不知道这一点,它会错误地引发异常。
  • 构造函数更糟糕。假设 D 类扩展了 C 类并覆盖了 invariant()。 D()调用C(),C()调用D.invariant(),这是错误的。 C 不必满足 D 的不变量,它比它自己的更强大。
  • 如果类外的客户端向方法传递了错误的参数,则 IllegalArgumentException 没有问题。但是如果调用者在类中,这是一个常规的旧契约违规。你想区分两者。 Gary Leavens 在这个 paper 中谈到了 JML 是如何做到的, 如果你有兴趣的话。
  • 用其他类方法表示的后置条件(即“后置条件”)在检查时会导致无限相互递归。

我的看法是 DbC 很有趣,如果语言有它(或者更好的是,像 Python 的函数装饰器),或者你有像 Modern Jass 这样的工具,然后深入研究。但是用纯 Java 做这件事是不可行的。也就是说,我正在研究不变检查 tool它生成的代码类似于您在此处所拥有的代码,但不存在调用链问题(它通过扩展类以接受知道何时进行检查的访问者来工作)。它需要Eclipse,自身也有问题(主要是private、static等坏词),但是检查机制是纯Java的。

关于java - 带有断言的契约(Contract)部分设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5126050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com