Defensive programming and Design by Contract on a routine level

“When quality is pursued, productivity follows” – K. Fujino, Vice President of NEC Cooperation’s C&C Software Development Group.

People are talking about how to create tools (Software Factories) that will increase productivity. The view of productivity has been important. With good productivity, we could build software rapidly and that will probably save us a lot of money. But will it in the end deliver software with high quality? The productivity could make the quality be left behind, in some organizations, productivity tend to be more important than quality. It’s important to know that quality on a product (or service) is its benefit to satisfy, or preferably exceed the customers’ requirements and expectations. By putting productivity before quality, will in short term goals save money, but will in long term cost more money.

A major component of quality in software is reliability. The software will be reliable when it performs its job according to the specification (correctness) and to handle abnormal situations (robustness).

If we look at correctness vs robustness from a developer’s perspective, correctness is met when a developer never returns an inaccurate result. It’s better to return no results than returning an inaccurate result. With robustness a developer always tries to do something that allows the software to keep operating, even if a result could be inaccurate sometimes. For safety-critical applications, correctness is more important than robustness. For example, it’s more important that software used in a chemical plant returns no results than wrong results. For a consumer application, it could be more important to flavor robustness than correctness. It’s better to return any result than shutting down a system, for example. It is better if a program closed down instead than showing a blue screen in Windows ;)

Reliable software has no bugs (reliability is the absence of bugs), or has it? Can software be completely free from bugs? Defensive programming and Design by Contracts will be a help to create reliable software with good correctness and/or robustness.

Defensive Programming

Defensive programming is about protecting yourself from being hurt by something dangerous (If bad data is sent to a routine, it will not hurt the routine). By writing code that will protect yourself from bad data, unexpected events, and other programmers mistakes, will in most case reduce bugs and create a high quality software.

Good programmers will not let bad data through. It’s important to validate input parameters to not let the garbage in. It’s also important to make sure that if garbage does come in, noting will goes out or an exception will be thrown. The following example is a result from defensive driven programming:

public Customer GetCustomerByName(string customerName)
{

   //validate so no garbage is getting through
   if (String.IsNullOrEmpty(customerName))
       throw new ArgumentException("The name of the customer is empty");

   try
   {

      //Get customer from data source

      Customer customer = ....
      //Make sure the customer is not null before the use

      //of its members in the compare method.            

      if (customer != null && String.Compare(customer.CustomerName, customerName) == 0)
         return customer; 
      else
         return null;
   }
   catch
   {
      throw;
   }
}

In the code above the input argument is first validated, if the validation failed, an exception is thrown. If the validation passes, the routine will try to get a customer from a data source by using the value from the customerName argument. If the customer was not found, nothing will out (returns null). If the routine fails to get the customer from the data source an exception will be thrown. In the example, correctness is more important than robustness. If robustness was more important, we could return an instance of an empty customer or “introducing Null object“ [Martin Fowler].

It’s important to both validate the input data, data returned from a data source and also use error handling to make sure a routine will not return any bad data if it fails. If the try and catch block are used, make sure an exception is passed on (thrown) and not only be catch within the catch block and then ignored, it could make the code more robustness but will violet correctness.

When using a defensive driven programming too much, it could create problems. Too much validation codes could make the code less readable and affect performance, so don’t overuse defense driven programming. Defensive programming will make error easier to find, easier to fix, and less damage to production code. The result of using defense driven programming will in return increase the quality of the software.

Design by Contract

Design by Contract is about is about creating a contract between the client and the supplier. The idea of the Design by Contract theory is to associate a specification with every software elements. This specification will define a contract between client and the supplier. When a supplier writes a contract with the client, it should document the obligations and benefits. When a client makes a call to the supplier, the supplier makes sure that the client follows the contract, this could be done by using precondition within a software routine (Client’s obligations to the code it calls) and postcondition (supplier’s obligations to the code that uses it). The following tabular form shows a contract between a client and its supplier, where an element is inserted into a dictionary:

              Obligations                                        Benefits
             (Must ensure precondition)                    (May benefit from postcondition)
Client
             Make sure dictionary is not full               Get the updated dictionary with the given
             and the element is not empty and           element.
             don’t already exists.
             (Must ensure postcondition)                  (May assume precondition)

Supplier
             Add the given element to the                Throw an exception if the dictionary is full
             dictionary.                                         or if the element is null.

C# doesn’t have support of specifying specifications (contracts). To use Design by Contract with C# we have to simulate it. A language that uses speciation for Design By Contract, is Eiffel. The following is an example in C# where post- and precondition is used (The contract simulated in this example, is the one specified in the tabular form above):

public void Add(object element)
{
   //precondition (require)
   if (element==null)
      throw new ArgumentNullException("element");

   if (this.IsFull)
      throw new Exception("The dictionary is full");

   if (this[element] == element)
      throw new Exception("The element already exists within the dictionary.");

   //do
   this._dictionary.Add(element);

   //postcondition (ensure)
   If (!this._dictionary.Contains(element))
      throw new Exception("The element is not added to the dictionary.");
}

If a client and a supplier have agreed over a contract where the supplier promises to return a result, the supplier should ensure to fulfill its demand, and the client will know that it will have a result and don’t need to check if it’s true. If the supplier failed to fulfill its demand at the first attempt, it should retry to fulfill its demand (rescue). The following example show an example of the previous code, but where the routines will retry to add an element even if the dictionary is full (Note: this is only pseudocode used by only showing the concept, that is why the code will try to add an element to the dictionary even if each loop will probably result in the same result):

public void Add(object element)
{

   //precondition (require)
   if (element==null)
      throw new ArugmentNullException(element);

   if (this[element] == element)
      throw new Exception("The element already exists within the dictionary.");

   bool fail;

   //rescue and retry
   for( int i = 0; i<100; i++)
   {
      try
      {
         this._dictionary.Add(element);
         fail = false;
      }
      catch
      {
         fail = true;
      }

      //retry
   }

   if (fail)
      throw new Exception("Can’t add element because the dictionary is full");

   //postcondition (ensure)
   if (!this._dictionary.Contains(element))
      throw new Exception("The element is not added to the dictionary.");
}

If C# should have support of adding specification to software elements, no validation code should need to be written in the way the example shows in the previous example, instead a contract should have been written. It could look something like this, where  "requires" is the precondition and the "ensures" is the postcondition:

public void Add(object element)
      requires element != null
           otherwise ArgumentNullException;
      requires this[element] != element
            otherwise Exception;
      requires !IsFull
            otherwise Exception;
      ensures this[element] == element
            otherwise Exception;
{
   this._dictionary.Add(element);
}

The Microsoft Research has created and overview of a new language called Spec# (similar to C# but uses contract "Method Contracts"). I hope this will be added to C# in the future.

I hope this post has given you some basic understanding about what Defense Programming and Design by Contracts is all about.

4 Comments

  • What is "violet correctness"?

  • I've always been a fan of Bertrand Meyer's DBC concept and his Eiffel programming language. It's too bad that Eiffel fell into obscurity.

    Being a C# developer and a big fan of DBC, I naturally checked out Spec# when I first discovered it a year or two back. I liked the implementation overall but found the VS integration to be unstable (at the time). One thing I didn't really care for was how it handled invariants.

    Unfortunately I don't really see Microsoft rolling Spec# into C# any time soon. They would ideally have to re-write all of the .NET base classes to make use of contracts (see how ArrayList was re-written). This would be a huge undertaking -- one I doubt they would take on even with all of their resources.

    These days though, I've seen my interest in DBC and Spec# decline in lieu of more dynamic (or functional) oriented programming. i.e. F#, LINQ, IronPython, IronRuby. It's not clear how something like Spec# would work in a dynamic, functional environment...

  • I can't agree with you more Fredrik

  • Why not using postsharp for this?

Comments have been disabled for this content.