RSS

A short intro on .NET Design by Contract approach

05 Aug

During software development debugging we frequently dig into functions or code libraries and eventually find out that the arguments passed in the first place was mistaken. For example, here is a method using NHibernate repository pattern:

/// <summary>
/// Get the product by the given ID
/// </summary>
/// <param name="productId">The product ID should be a positive integer</param>
/// <returns></returns>
public Product GetProductById(int productId)
{
    ProductRepository productRepository = new ProductRepository();
    Product product = productRepository.GetById(productId);

    return product;
}

It happens so often that we fail to notice the comment when calling this method and get a null object from it. We then debug “Object reference not set to an instance of an object” error and figure out the ID should be a positive integer(not that easy to make such an apparent mistake though…). The problem is easy to spot here but not in a more complex method. By applying Design by Contract(DbC) approach the error can be instantly exposed and the method is more robust:

public Product GetProductById(int productId)
{
    //Precondition - what this method expects
    if (productId <= 0)
        throw new ArgumentOutOfRangeException("productId", "sould be a positive integer");

    ProductRepository productRepository = new ProductRepository();
    Product product = productRepository.GetById(productId);

    //Postcondition - what this method guarantees
    if (product == null)
        throw new NullReferenceException("Product not found");

    return product; 
} 

Using DbC makes methods self-documented and debugging easy. Despite of its benefits, writing codes in every method like this is cumbersome. Code Contracts, the DbC implementation by Microsoft makes our life easier:

 
public Product GetProductById(int productId) 
{     
    //Precondition
    Contract.Requires(productId > 0, "productId sould be a positive integer");

    ProductRepository productRepository = new ProductRepository();
    Product product = productRepository.GetById(productId);

    //Postcondition
    Contract.Ensures(product != null, "Product not found");

    return product;
}

Code Contracts supports Precondition, Postcondition, Object invariant and much more. Please refer to their project page. For more detailed DbC introduction please refer to Design-by-Contract: A Practical Introduction.

References:
Design-by-Contract: A Practical Introduction
Design by Contract Framework
Code Contracts

Advertisements
 
Leave a comment

Posted by on August 5, 2012 in .NET, C#, OOP

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: