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!

Monday, November 26, 2007

Exception Handling Anti-patterns

Exception Handling Anti-patterns:

Rather than discussing best patterns, it is important to discuss anti-patterns for specific concepts, where such concepts are misunderstood most of the time. In this post, we will discuss anti-patterns in Exception Handling.

Once an Exception is thrown, then never catch it; Never catch it unnecessarily.

This is a thumb rule of exception handling. Once an exception is thrown, then it should be never caught, until it propagates to the top level caller. Otherwise, it will turn very difficult to trace the exception flow in the code. Exception should not be caught unless it is going to be consumed (ignored), or there is some code to be run in the catch block.

The following example can illustrate it.

private void methodA(String name) throws ABCException
{
methodB(name);
}
private void methodB(String name) throws ABCException
{
methodC(name);
}
private void methodC(String name) throws ABCException
{
if (name == null) //thrown here
throw new ABCException("Name arg can not be null.");

//else do something..
}

methodC() throws ABCException, but methodA() and methodB() do not catch the ABCException any where, they just allow the exception to propagate to their callers. In this example, the ABCException should not be caught in methodB() or methodA() unless it is necessary. It is very common mistake that developer unnecessarily catch exception.

Also, don’t catch the exception just for logging or printing the information; only the top level caller has to log the exception – other wise the same exception will be logged many times.

Never throw Runtime exceptions.

Any exception (or custom exception), that is a subclass of java.lang.RuntimeException is a runtime exception, i.e: NullPointerException, ArrayIndexOutOfBoundsException.

Because, the runtime exceptions occur in exceptional cases, that can not be handled. A program or an application should not throw any runtime exception. Any program that throws runtime exception is buggy. So, runtime exception should not be thrown at all from the code or it should not be caught in the code at all (let it propagate, so that you would come to know that it is a code bug).

Sample code snippet that catches a runtime exception.

try
{
quotient = numerator / denominator;
}
// This is bad, dont catch!
catch (ArithmeticException arithmeticException)
{
// some code goes here..
}


In the above example, there are two bad things!

1. The code should not catch the runtime exception (ArithmeticException)

2. The code should be written smart enough to avoid possible runtime exceptions; In this case, the program should validate the denominator before dividing – so that ArithmeticException will not occur.

The above code can be re-written as:

if (denominator == 0)
throw new XYZApplicationValidationException("Denomintor can not be null!");

quotient = numerator / denominator;

The second code snippet does not catch runtime exceptions and also avoids possible runtime exceptions.

Do not throw simply java.lang.Exception or Multiple checked exceptions.

Most common mistake in exception handling is, just throwing java.lang.Exception! If a method throws java.lang.Exception then all of it’s callers are forced to throw java.lang.Exception or wrap java.lang.Exception!; this is worst case, because it restricts the reusability of code. Other developers may hesitate to call this method as it is difficult to throw or wrap java.lang.Exception.

private void methodA(String name) throws Exception
{
//…..code
}

It is very hard to reuse methodA !

Also, a method throwing multiple checked exceptions may look tough! Instead of throwing multiple checked exceptions, the method can throw the parent of all those checked exceptions. It does not affect the exception flow, but same time, it makes the method declaration to look clean.
Ex:

public void methodA() throws BException, CException, DException
{}

In the above example, if AException is the parent of BException, CException and DException, the method declaration can be rewritten as,

public void methodA() throws AException
{}


The later version of method declaration looks pretty clean than the former.

When wrapping exceptions, the root exception info should not be lost.

When wrapping exceptions, it is important to copy all information of the root exception.

catch(ABCException abcException)
{
String rootExceptionMsg = abcException.getMessage();

throw new MyCustomException(rootExceptionMsg);
}

In the above example, MyCustomException wraps the root exception (ABCException). But, StackTrace of the ABCException is lost, any error code, any parameter and any other information of ABCException is also lost! Care should be taken to copy all info. Also, the wrapping exception class should be designed such that it stores the instances of the root exceptions (so that stack trace and other info can also be stored).

Careful design of Custom Exception.

  • Custom exception can be a runtime exception unless it is necessary to be a checked exception. Because, all the callers have to declare it or handle it or wrap it.
  • It is good to store instances of all root exceptions in custom exception (though it adds weight to custom exception instance, this will be useful to dig exception later).
  • Do not create separate exception class for each error scenario. Too much of exception classes will be hard to maintain.
  • Pass all necessary parameters in exception message.

Write code such that it will not lead to runtime exception.

Code should be written such that it will not lead to any runtime exceptions. NullPointerException is the most common runtime exception we face. Let’s discuss the common runtime exception cases.

  • Before accessing any attribute or calling any method on an instance, do a null check.

if (str1.equals(str2))
//...

Above ‘if’ condition will lead to NullPointerException, if str1 is null. It can avoid NullPointerException, if the code is rewritten as,

if ( str1 !=null && str1.equals(str2))
//…..

  • Do not return null from a method, return zero length array instead

public String [] getNames()
{
return null;
}

The caller of getNames() may not do a null check, so it is better to return zero length array also instead of returning null.

public String [] getNames()
{
return new String[0]
}

Welcome all.

Welcome all. Here by I am starting a new blog on ‘Java, J2EE design and architecture’.

What is this blog all about?

This blog will have posts about design and architectural discussion, patterns, issues in Java and J2EE. Note, this is not yet another technical blog to discuss ‘how to program’ in Java or J2EE.

Who can be the readers?

Any one knowing Java programming language or any other OO language. Also, people interested in knowing system design and system architecture.

Whats the frequency of posts?

At least one post per week.