Question

Do you use Design by Contract professionally? Is it something you have to do from the beginning of a project, or can you change gears and start to incorporate it into your software development lifecycle? What have you found to be the pros/cons of the design approach?

I came across the Design by Contract approach in a grad school course. In the academic setting, it seemed to be a pretty useful technique. But I don't currently use Design by Contract professionally, and I don't know any other developers that are using it. It would be good to hear about its actual usage from the SO crowd.

Was it helpful?

Solution

I can't recommend it highly enough. It's particularly nice if you have a suite that takes inline documentation contract specifications, like so:

// @returns null iff x = 0
public foo(int x) {
  ...
}

and turns them into generated unit tests, like so:

public test_foo_returns_null_iff_x_equals_0() {
  assertNull foo(0);
}

That way, you can actually see the tests you're running, but they're auto-generated. Generated tests shouldn't be checked into source control, by the way.

OTHER TIPS

You really get to appreciate design by contract when you have an interface between to applications that have to talk to each other.

Without contracts this situation quickly becomes a game of blame tennis. The teams keep knocking accusations back and forth and huge amounts of time get wasted.

With a contract, the blame is clear.

Did the caller satisfy the preconditions? If not the client team need to fix it.

Given a valid request, did the receiver satisfy the post conditions? If not the server team need to fix that.

Did both parties adhere to the contract, but the result is unsatisfactory? The contract is insufficient and the issue needs to be escalated.

For this you don't need to have the contracts implemented in the form of assertions, you just need to make sure they are documented and agreed on by all parties.

If you look into STL, boost, MFC, ATL and many open source projects, you can see there are so many ASSERTION statements and that makes project going further more safely.

Design-By-Contract! It really works in real product.

Frank Krueger writes:

Gaius: A Null Pointer exception gets thrown for you automatically by the runtime, there is no benefit to testing that stuff in the function prologue.

I have two responses to this:

  1. Null was just an example. For square(x), I'd want to test that the square root of the result is (approximately) the value of the parameter. For setters, I'd want to test that the value actually changed. For atomic operations, I'd want to check that all component operations succeeded or all failed (really one test for success and n tests for failure). For factory methods in weakly-typed languages, I want to check that the right kind of object is returned. The list goes on and on. Basically, anything that can be tested in one line of code is a very good candidate for a code contract in a prologue comment.

  2. I disagree that you shouldn't test things because they generate runtime exceptions. If anything, you should test things that might generate runtime exceptions. I like runtime exceptions because they make the system fail fast, which helps debugging. But the null in the example was a result value for some possible input. There's an argument to be made for never returning null, but if you're going to, you should test it.

It's absolutely foolish to not design by contract when doing anything in an SOA realm, and it's always helpful if you're working on any sort of modular work, where bits & pieces might be swapped out later on, especially if any black boxen are involved.

In lieu of more expressive type systems, I would absolutely use design by contract on military grade projects.

For weakly typed languages or languages with dynamic scope (PHP, JavaScript), functional contracts are also very handy.

For everything else, I would toss it aside an rely upon beta testers and unit tests.

Gaius: A Null Pointer exception gets thrown for you automatically by the runtime, there is no benefit to testing that stuff in the function prologue. If you are more interested in documentation, then I would use annotations that can be used with static analyzers and the like (to make sure the code isn't breaking your annotations for example).

A stronger type system coupled with Design by Contract seems to be the way to go. Take a look at Spec# for an example:

The Spec# programming language. Spec# is an extension of the object-oriented language C#. It extends the type system to include non-null types and checked exceptions. It provides method contracts in the form of pre- and postconditions as well as object invariants.

Both Unit testing and Design by Contract are valuable test approaches in my experince.

I have tried using Design by Contract in a System Automatic Testing framework and my experience is that is gives a flexibility and possibilities not easily obtained by unit testing. For example its possible to run longer sequence and verify that the respons times are within limits every time an action is executed.

Looking at the presentations at InfoQ it appears that Design by contract is a valuable addition to the conventional Unit tests in the integration phase of components. For example it possible to create a mock interface first and then use the component after- or when a new version of a component is released.

I have not found a toolkit covering all my design requirement to design by contract testing in the .Net/Microsoft platform.

I don't actually use Design by Contract, on a daily basis. I do, however know that it has been incorporated into the D language, as part of the language.

Yes, it does! Actually a few years ago, I designed a little framework for Argument Validation. I was doing a SOA project, in which the different back-end system, did all kind of validation and checking. But to increase response times (in cases where the input was invalid, and to reduce to load those back-end systems), we started to validate the input parameters of the provided services. Not only for Not Null, but also for String patterns. Or values from within sets. And also the cases where parameters had dependencies between them.

Now I realize we implemented at that time a small design by contract framework :)

Here is the link for those who are interested in the small Java Argument Validation framework. Which is implemented as plain Java solution.

I find it telling that Go programming language has no constructs that make design by contract possible. panic/defer/recover aren't exactly that as defer and recover logic make it possible to ignore panic, IOW to ignore broken contract. What's needed at very least is some form of unrecoverable panic, which is assert really. Or, at best, direct language support of design by contract constructs (pre and post-conditions, implementation and class invariants). But given strong-headedness of language purists at the helm of Go ship, I give little change of any of this done.

One can implement assert-like behaviour by checking for special assert error in last defer function in panicking function and calling runtime.Breakpoint() to dump stack during recovery. To be assert-like that behaviour needs to be conditional. Of course this approach fells apart when new defer function is added after the one doing assert. Which will happen in large project exactly at the wrong time, resulting in missed bugs.

My point is that is that assert is useful in so many ways that having to dance around it may be a headache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top