Skip to Content

“Design by Contract” is an object-oriented technique which defines contracts for the main program elements – methods and classes [1]. The client code must adhere to the contract otherwise the result is undefined. The contract consists of three main elements – preconditions, postconditions and invariants. Preconditions and postconditions are applied to functions, while invariants are applied to classes. Preconditions define what have to be true when a method is called, the client code must call the function in such a way that the precondition is met. Postconditions are the callee part of the contract; the function is obliged to meet the postconditions in the end of its execution. Invariants hold true for a certain class and is true for every object of that class. Preconditions and postconditions can be applied to interface or abstract functions. The overloading function from a class down in the hierarchy must meet the contract – the rule is that precondition can be kept or weaken, while postconditions can be kept or strengthen.  Following this rule we can use an interface without worrying about any of its implementation classes.  This is also known as “Liskov substitution principle” [2]. A violation of the contract means a programmer error therefore contracts should not be used to validate user’s input or data which is external to the system – you have the plain old exception mechanism.

Some of the benefits of the “Design by Contract” include

  • Better debugging, testing and quality assurance of the source code, since it detects violations of the entities’ contracts earlier – bugs are found closer to where they are.
  • Better documentation of the source components, thus better understanding of them.
  • Better approach to specify object-oriented elements

Togehter with unit tests and “Test driven development”  “Design by Contract” can help toward to goal of software with fewer bugs.

“Design by Contract” was introduced by Dr. Bertrand Meyer in the Eiffel programming language which has built-in support for it. Here is a sample function written in Eiffel:

decrement is
  require
      item > 0
  do
      item := item - 1
  ensure
      item = old item - 1
  end

Although this is pretty trivial function, it gives a notion of how Eiffel treats “Design by Contract”. It is possible to define preconditions and postconditions to interface methods. This facilitates the design process due to the semantic expressiveness of the contract.

In Java the easiest is to use custom-made class for the assertion statements and insert the preconditions and postconditions as assertion statements at the beginning and the end of the functions. Another solution is to use the built-in assert key words in JDK 1.4. Although these techniques provide more informal treatment of the Design by Contract they are still beneficial. Here is an example of the built-in java asserts construction:

void push (int data) {
  assert !isFull();
  int oldCount = count;

  stack[count++] = data;

  assert count == oldCount+1;
  assert top() == data;
}

It is better that asserts (being custom or built-in) are disabled in production systems. They are useful in test systems, but in production systems they carry out performance implications. The built-in assert key words are in fact by default disabled at runtime, you need to explicitly supply the -enableassertions parameter of the JVM of your development or test system. Another solution is to write the assert statements like this:

static final boolean DEBUG = ...;
...
if (DEBUG)
  assert expression;

then if the DEBUG field is set to false, an optimizing java compiler will treat the assert statement as unreachable code and will not add it to the compiled class file.

Another way to perform “Design by Contract” is by using aspect-oriented programming with AspectJ [3]. That way the preconditions, postconditions and invariants are not mixed with the source code, but they live in a separate aspect class. Other tools for “Design by Contract” are for example iContract, jContractor, DBCProxy, JMSAssert and so on. “iContract” [4] for example is a preprocessor tool for java, it preprocesses the source code files producing additional classes to deal with the Design by Contract, and finally run the java compiler. A sample function in java with iContract looks like:

/**
* @pre !isFull()
* @post count == count@pre+1
* @post top() == data
*/
void push (int data) {
  stack[count++] = data;
}

Postconditions can indirectly be implemented with unit tests – violating a postcondition means an error in the called method. I this is also somewhat true for invariants, on the other hand violating a precondition implies an error in the caller code – this sometimes is hard to be caught by unit tests. Assertions in “Design by Contract” look like static testing (declarative), while unit tests resemble dynamic one. “Design by contract” and unit tests complement to each other, and assert statements can be very helpful when automated UI tests are being executed.

 

References:
[1] [eiffel.com] An introduction to Design by Contract
[2] [objectmentor.com] Liskov substitution principle
[3] [ibm.com] Contract enforcement with AOP
[4] [javaworld.com] iContract: Design by Contract in Java
[5] [C2 Wiki] Design By Contract

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. Bertrand LAFOUGERE
    Design by contract is, as state Bertrand Meyer in it’s bible on object, a best practice for OO but I think that the “client developper that will consume” the class has to be aware of the contracts (I’m not sure it’s mantatory in the theory … )
    Here is the limitation in abap as we don’t have a phpDocumentor / JDoc (?) stuff neither assertion (well before 6.40).

    Can we really design by contract without both ? I don’t think so. Now Java as “the father of all theses new design paradigm” is armed to faced them but the abap is still lacking many of them.

    (0) 
    1. Daniel Simeonov Post author
      Hi Bertrand,
         I think also that the client code should be written with knowledge of the contract of the target element (method), otherwise there is a moment of guessing. Unfortunatelly I have very little experience with ABAP, but as I remember  everything is stored as source code, i.e. you can see the source and the comments of the target function for example. 
      Best regards, Daniel.
      (0) 
  2. Andreas Blumenthal
    Assertions are available in ABAP since 6.20 SP 29, so you can realize “Design by Contract” and especially pre-/post-conditions in ABAP via assertions like in Java.

    ABAP’s assertion mechanism is even better suited for realizing pre-/post-conditions than Java’s assertion mechanism, because in ABAP, assertions can (and should !) be assigned to checkpoint groups, thus enabling the selective activation of assertions assigned to semantically meaningful checkpoint groups even in production systems.

    Regarding ABAPDoc: if there is a need, we would like to implement it, so we would like to encourage the SDN community to express whether there is a need or not.

    (0) 

Leave a Reply