Sunday, December 2, 2007

Great Programmers secret #1: Reusability

Great Programmers secret #1: Reusability

Long back, I visited a site, where they’ve listed the best sample programs written in a programming contest. Couldn’t find anything great in the code at first sight. When looked at the code keenly, with the curiosity to know why they were said to be great, I was in great surprise. The programs used lots of standard library functions – we may not be even knowing many of such library functions really exist!

The programs are graded based on many programming standards, but the foremost criterion is ‘Reusability’.

Consider this example,

String [] fruits = {"nuts", "dates","apple", "orange", "banana"};
String [] dryFruits = new String[2];

Suppose, if we need to copy the first two elements (or ‘n’ elements) of fruits[]array into dryFruits[] array, most of us immediately start with a for loop. That’s some thing like,

for(int i=0; i<2; class="SpellE">i++)
{
dryFruits[i] = fruits[i];
}

The above code is clean, simple, extensible and nothing wrong in it. But, still, what is the overhead in it? We need to test the code at least once. We need to give proper comments or explain the logic to the reader or code maintainer. But, what if we utilize or reuse some standard library function and rewrite the same logic as,

System.arraycopy(fruits,0,dryFruits,0,2);

We saved time from doing:

  1. Testing the code (Because, System.arraycopy()library was tested well already).
  2. Explaining/documenting the logic (Because, System.arraycopy()is a standard library, already documented, accessible to all).

Importance of Reusability:


Reusability reduces testing work:

When we use common libraries or reuse somebody else’s utilities, we can be comfortable since, the utilities or libraries were already tested.

Maintainability and Manageability:

As the code is in common place, it is very easy to make changes, so that the change reflects every where without any inconsistency.

Removing the boilerplate:

In most of the cases, we repeat the same chunk of code here and there in the application (this is known as boilerplate). The common code/logic should be extracted and put in one place, so that maintainability and manageability will become easier. (Note: here, the terms ‘maintainability’ and ‘manageability’ are not used to make a rhyming sentence! they are really different terms and really important!).
To extract the common code, use code refactoring tools (Eclipse, Netbeans and almost all rich IDEs supports code refactoring). I personally suggest the IDE, ‘Intellij-Idea’ which supports lots of code refactoring rules.

Logic need not be rewritten, instead it can be overridden:

In some cases, we will not be able to completely reuse some libraries or code. We may be able reuse only a portion of the logic. In this case, we need not to rewrite everything from the scratch. We can reuse the same code/logic as far as possible, and can override the changing part.

Assume, we have ReportUtil class, that reads data using readData() and prepares report using prepareReport() and sends the report by mail using sendReport().

class ReportUtil
{
private void readData()
{
//..............
}
private void prepareReport()
{

//.......
}

private void sendReport()
{

//.......
}
}

Suppose, if we need to have another class that does same thing as ReportUtil, except one task -- that’s the new class will send the report by Fax (instead of emailing).

We don’t need to write a complete new class from scratch or copy/paste the code from ReportUtil to new class. Let the new class (give a name ‘FaxReportUtil) reuse the ReportUtil class (in this case ‘extends’) and override the sendReport() method to send the report by Fax. Now, its enough to test only the sendReport() method, because we have made changes only in that method!

No comments: