由合同和建设者设计 [英] Design by contracts and constructors

查看:20
本文介绍了由合同和建设者设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为学校目的实现我自己的 ArrayList,但为了让事情更有趣,我正在尝试使用 C# 4.0 代码合同.一切都很好,直到我需要向构造函数添加合同.我应该在空参数构造函数中添加 Contract.Ensures() 吗?

I am implementing my own ArrayList for school purposes, but to spice up things a bit I'm trying to use C# 4.0 Code Contracts. All was fine until I needed to add Contracts to the constructors. Should I add Contract.Ensures() in the empty parameter constructor?

    public ArrayList(int capacity) {
        Contract.Requires(capacity > 0);
        Contract.Ensures(Size == capacity);

        _array = new T[capacity];
    }

    public ArrayList() : this(32) {
        Contract.Ensures(Size == 32);
    }

我会说是的,每种方法都应该有一个明确定义的契约.另一方面,如果它只是将工作委托给主"构造函数,为什么要放它呢?从逻辑上讲,我不需要.

I'd say yes, each method should have a well defined contract. On the other hand, why put it if it's just delegating work to the "main" constructor? Logicwise, I wouldn't need to.

我认为在两个构造函数中显式定义合约的唯一一点是,将来我们是否有对合约的 Intelisense 支持.如果发生这种情况,明确说明每种方法具有哪些合同会很有用,因为这会出现在 Intelisense 中.

The only point I see where it'd be useful to explicitly define the contract in both constructors is if in the future we have Intelisense support for contracts. Would that happen, it'd be useful to be explicit about which contracts each method has, as that'd appear in Intelisense.

此外,是否有任何书籍更深入地介绍了契约式设计的原则和用法?一件事是了解如何在语言(在本例中为 C#)中使用契约的语法,另一件事是知道如何以及何时使用它.我阅读了一些教程和 Jon Skeet 的 C# in Depth 文章,但如果可能的话,我想更深入一些.

Also, are there any books around that go a bit deeper on the principles and usage of Design by Contracts? One thing is having knowledge of the syntax of how to use Contracts in a language (C#, in this case), other is knowing how and when to use it. I read several tutorials and Jon Skeet's C# in Depth article about it, but I'd like to go a bit deeper if possible.

谢谢

推荐答案

我完全不同意 Thomas 的回答.只要您在 ArrayList() 的实现中做出选择,您就应该有一个合同来记录这些选择.

I completely disagree with Thomas's answer. As long as you are making choices in the implementation of ArrayList(), you should have a contract for it that document these choices.

在这里,您选择使用参数 32 调用主构造函数.您可以决定做许多其他事情(不仅仅是关于默认大小的选择).给 ArrayList() 一个契约,它几乎与 ArrayList(int) 文档的契约相同,你决定不做大多数你可以做的愚蠢的事情,而不是直接调用.

Here, you are making the choice of calling the main constructor with argument 32. There are many other things that you could have decided to do (not just concerning the choice of the default size). Giving a contract to ArrayList() that is almost identical to that of ArrayList(int) documents that you decided not to do most of the silly things you could have done instead of calling it directly.

它调用主构造函数,所以让主构造函数的契约来完成工作"的答案完全忽略了这样一个事实,即契约的存在是为了让您不必查看实现.对于基于运行时断言检查的验证策略,即使对于几乎直接调用另一个构造函数/方法的如此短的构造函数/方法,编写契约的缺点是您最终会检查两次.是的,这似乎是多余的,但运行时断言检查只是一种验证策略,DbC 的原则与其无关.原则是:如果可以调用,就需要一个契约来记录它的作用.

The answer "it calls the main constructor, so let the main constructor's contract do the job" completely ignores the fact that the contract is there to save you from having to look at the implementation. For a verification strategy based on run-time assertion checking, the disadvantage of writing contracts even for such short constructors/methods that almost directly call another constructor/method is that you end up checking things twice. Yes, it seems redundant, but run-time assertion checking is only one verification strategy, and DbC's principles are independent from it. The principle is: if it can be called, it needs a contract to document what it does.

这篇关于由合同和建设者设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆