首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有断言的合同的部分设计

带有断言的合同的部分设计
EN

Stack Overflow用户
提问于 2011-02-26 17:14:05
回答 3查看 561关注 0票数 1

我想就部分实现契约式设计的想法征求一些意见。我们的目标是向那些不提供它的语言添加一个轻量级的契约(仅限于不变式和post条件),而不需要外部库。

我的示例是用Java编写的,但我认为这个想法适用于许多面向对象语言。

我们有一个这样的类:

代码语言:javascript
复制
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
    }
}

我们以这种方式扩展上面的代码:

代码语言:javascript
复制
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
    }
}

此方法的局限性:

代码语言:javascript
复制
 - no pre-conditions.
 - the contract is not inherited (but please note that invariant and post-conditions are protected and can be reused by a subclass).
 - there isn't any check that invariant and post-conditions don't modify the state of our object, hence there is a risk of side effects.
 - the contract is not part of our documentation in a clear way.
 - we need to make cloneable every class.

现在,有几个问题:

代码语言:javascript
复制
 - does this method hurt the performances in any way? I mean even the old and res local variables are removed by the JIT compiler if assertions are disabled?
 - do you see any downside of this approach? Why wouldn't you use this in your classes?
 - can you suggest any improvement?

感谢您的阅读和您的意见。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-24 05:55:36

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

在有限的应用程序中,它有点-排序工作。但是,由于契约规范不必担心真正的代码会出现“谁在调用谁”之类的问题,因此出现了很多问题。

  • 说你有一些方法F,它调用另一个方法G。想象一下,F在运行时破坏了rep不变量,但在返回之前修复了一些东西。这是允许的,在某些情况下是必需的,但G不知道这一点,它会错误地引发更糟糕的exception.
  • Constructors。比方说,类D扩展了类C并覆盖了不变性()。D()调用C(),C()调用D.invariant(),这是错误的。C不需要满足D的不变量,D的不变量比它自己的更强。
  • 如果一个方法被类外的客户端传递了错误的参数,那么IllegalArgumentException就没问题。但是如果调用者在类内部,这就是常规的旧约定冲突。您想要区分这两者。Gary Leaven谈到了JML是如何在这个paper中做到这一点的,如果你是用其他类方法(也就是“interested.
  • Postconditions”)表达的,那么当你选中它时,会导致无限的相互递归。

我的观点是DbC很有趣,如果该语言有它(或者更好,像Python的函数装饰器),或者您有像Modern Jass这样的工具,那么就深入研究一下。但是在纯Java中做这件事是不可行的。也就是说,我正在开发一个不变的检查tool,它生成的代码类似于您在这里拥有的代码,但没有调用链问题(它的工作方式是通过扩展类来接受访问者,该访问者知道何时进行检查是合适的)。它需要Eclipse,并且有它自己的问题(主要是相关的不好的词,如private和static),但是检查机制是纯Java的。

票数 2
EN

Stack Overflow用户

发布于 2011-02-26 18:44:40

如果你想要Java的“契约式设计”,你可能想看看(真正的)大人物是如何做到的!以下是Google最近在"Contracts for Java“中对这个主题的看法:

http://google-opensource.blogspot.com/2011/02/contracts-for-java.html

现在回答你的两个问题:

代码语言:javascript
复制
- do you see any downside of this approach? Why wouldn't you use this in your classes?

因为它的一个缺点是它非常冗长:如此冗长以至于代码几乎无法阅读。

代码语言:javascript
复制
- can you suggest any improvement?

不要重复发明轮子..。

票数 2
EN

Stack Overflow用户

发布于 2011-02-26 19:01:39

你认为这种方法有什么缺点吗?你为什么不在你的课堂上使用它呢?

我编写的大多数Java类都是不可克隆的,因为用Java语言实现Clonable并非易事。因此,当它不是绝对必要时,我不会实现它。我不想仅仅为了你的方法而这样做。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5126050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档