Friday, April 10, 2009

Building quality and bug free software : Leverage Design By Contract

Since inception, the advent of Object orientation development gave birth to chains of concepts in recent years, and all these had positive impacts on the ways we develop robust, reliable and scalable systems that passes the test of time. One of this concept is designing software component and allowing components interaction based on contracts. These contracts are the full agreements that each components must satisfy before the system can run successfully.

A simple analogy is smashing a bottle on the floor, what do we expect? of course, we'd expect the bottle to break, and scattered all over the floor. The fact that the action smashing a bottle on the floor requires a bottle (Pre-conditions) and bottle must scatter on the floor (Post- condition). The pre-conditions and post-conditions are the contract agreement in our analogy. Now lets dig into what really is design by contract:

What is Design By Contract (DBC)

Design by contract is the ability of software components to satisfy obligations that are required for the smooth running of a software systems. Was introduced into the Eiffel programming language designed by Bertrand Meyer in 1988.


Now, the word design by contract is used to associate software contracts/specifications with the software development itself, by so doing, we described what the software component expects from calling component or client. This approach makes the development of software and its specification to be interwoven and changed when either changes.

Again What is Design By Contract

Design by contract is a software development standards that enforces a pre-conditions and post-conditions on the ways software components/ methods and libraries communicate with one another. An object oriented class should depict what it represents. If you have a class called AccountValidator, the job of that class is to validate an Account not to withdraw from that account, another class or service will handle the withdraw aspect.

To validate an account, we will Require an Account Details object, and the algorithms for validating an account, and also Ensure that the account is valid, and there is no invalid data supplied. Note the two words Require and Ensure , these are analougous to the pre-conditions and post-conditions that we have been refering to. So if you are developing the AccountValidator class, the methods should require that parameters meets its demand and ensure that valid validation response is sent to the consumer.

Why all this, what about TDD (Test Driven Development)

Yeap, TDD allows you to pre-verify your code against certain conditions too. And if you have been using Assert statements to verify outputs from your test, you are near design by contract. But DBC allows you to have the assertions into your code not outside your code. Your methods should be strict enough and only bound to its part of the contract.

All talk and no code : Tell me more

Now lets consider the following class AccountValidator, and its contract obligations :


interface IAccountValidator
{
bool ValidateAccount(IAccountDetails account);
}


//IAccountValidator Implementation

public class AccountValidator : IAccountValidator
{
public bool ValidateAccount(IAccountDetails account)
{
if (ValidateAccountNumber(account.AccountNumber))
{
if (ValidateNameOnAccount(account.NameOfAccount))
{
//Now ensure that the value is in the database

if(ValueIsInDataBase(account))
return true;
}
}

return false;
}

private bool ValidateAccountNumber(string accountNumber)
{
if (string.IsNullOrEmpty(accountNumber))
throw new InvalidOperationException("Invalid Account Number");

if (accountNumber.Length != 8)
throw new InvalidOperationException("Account number must be exactly 8 characters long");

return true;
}

private bool ValidateNameOnAccount(string name)
{
if (string.IsNullOrEmpty(name))
throw new InvalidOperationException("Invalid Account Name");

return true;
}

private bool ValueIsInDataBase(IAccountDetails account)
{
//Database calls here
}
}




The class above specifies to pre-conditions, these are valid account number and valid account name. The post-conditions of this class would have been checking that the actual data submitted is valid in the database. This class is just a simple and classic design by contract example, more advanced frameworks has been produced using aspect weaving or aspect oriented programming to solve the contract issues.

DBC is comming in .NET 4.0

Code contracts will be part of the Rosairo project (VS 2010). This will allow you to have the ability of static time checking of contract violations, API documentation, improve your testability.