Friday, December 28, 2007

Design Patterns & Anti Patterns


Architecture and Patterns are the terms borrowed from Civil Engineering. Christopher Alexander, a great Civil Architect, had documented more than 250 patterns in his book ‘Pattern Language – (1977)’ related to Civil Engineering (online copy of the book is available here: http://downlode.org/Etext/Patterns/). As inspired by the pattern language, software engineering has formulated its own patterns for software system development.

Design Pattern - What does it really mean?

In simple terms, ‘it’s a proven solution’. A pattern is composed of problem statement and solution details. It should be technology or language neutral.

Why should one use it?

‘Pattern’ is something that is commonly documented. When you use something that’s common for all, people can easily understand it. Pattern will help you when you code/implement complex designs.

Are the Design Patterns specific to Object-Oriented system?

Need not to be. Design Patterns are heavily used in context of Object Oriented design. All the examples and tutorial we find on books and Internet talk about Design Pattern in OO.

For structural specific design problem one can go for Recipes.

What is Recipe?

Recipe is a documented, sequential set of instructions for a recurring, specific, design issue in Structural language like Assembly, C and etc.

How many Design Patterns are there?

They are countless. As people come up with a new pattern every now and then, it is very difficult to document them. However, a Gang Of Four has documented 23 patterns, and they are the most common, and popular patterns in OO design. You can refer the following book ‘Design Patterns - Elements of Reusable Object Oriented Software’ for details.

As this age is for frameworks, we can find lots of patterns that are specific to frameworks.

What are all the patterns specific to J2EE Framework?

There are so many. There are patterns for each and every tier. I personally recommend to start from here: http://java.sun.com/blueprints/corej2eepatterns/Patterns/. Sun has well documented the core design patterns for J2EE.

Is it mandatory to use patterns? Some of the design problems not covered by any patterns, what to do in this case?

Choice is yours. More you use the patterns, more you generalize your design or implementation. Coming to the second question, design problems are specific in most of the cases. So, there cannot be a pattern for every design problem you face. Suppose, if you find the scenario is recurring frequently, and not yet documented, you can document it as a new pattern. Most of the time, it will be a mixture of existing patterns.

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!