Thursday, December 18, 2008

Preconditions, Postconditions, Invariants : Design by Contract for Java #2

Recently I wrote about how to apply "Design by Contract" with Java. I proposed to use the assert statement of java, in case you do not want to set up some external tools like Contract4J, iContract or Jass. After using the assert statement for a while I would recommend to use your own implementation of assertions instead like this:
public class Assertion {

 /**
  * Precondition.
  * @param condition we expect to be true.
  * @param description repeats the condition or describes it in
  * other words.
  */
 public static void Require(boolean condition, String description) {
     if (!condition) {
         throw new RuntimeException("Precondition: The expectation '" + description + "' is violated");
     }
 }

 /**
  * Precondition.
  * @param objectToBeTested is an object we expect to be not null
  * @param objectName is the name of the variable we test.
  */
 public static void RequireNotNull(Object objectToBeTested,String objectName) {
     if (objectToBeTested == null) {
         throw new RuntimeException("Precondition: The expectation '" + objectName + " is not null' is violated");
     }
 }

 /**
  * Postcondition.
  * @param condition we expect to be true.
  * @param description repeats the condition or describes it in
  * other words.
  */
 public static void Ensure(boolean condition, String description) {
     if (!condition) {
         throw new RuntimeException("Postcondition: The expectation '" + description + "' is violated");
     }
 }

 /**
  * Common condition to be used in the middle of methods
  * @param condition we expect to be true.
  * @param description repeats the condition or describes it in
  * other words.
  */
 public static void Check(boolean condition, String description) {
     if (!condition) {
         throw new RuntimeException("Condition: The expectation '" + description + "' is violated");
     }
 }
}
Why is the own implementation better than the assert statement?
  1. It does not make sense to switch off the runtime checks of assertions. We use assertions to simplify and avoid the error handling code in our methods. When it is possible to switch of assertions we loose this advantage, because we have to prepare our code to handle situations where the assertions are not checked.
  2. We are not only profiting from assertions during development and testing but also when the software is deployed. Assertions uncover error conditions much clearer and with better error descriptions. The logs in a production system will contain the messages from assertions and will help to find the cause of the problem much faster. If we switch off the assertions the problems will occurring much later and the cause of the problem can only be found with much more effort,
You can find details about "Design by Contract" in the famous book Object-Oriented Software Construction by Bertrand Meyer.

No comments: