Wednesday, March 25, 2009

Java 7:Multiple exception catch block

Java 7 proposes a new syntax for catching multiple exceptions in a single catch block (http://www.javac.info/Multicatch.html). It looks like a neat feature to have and the new syntax is definately better than having multiple catch blocks with the same exception handling code.
So instead of -

try{
// Some code that throws ServiceException and WebsiteException
}
catch(ServiceException exception) {
Logger.Log(exception);
throw ApplicationException(exception);
}
catch(WebsiteException exception){
Logger.Log(exception);
throw ApplicationException(exception);
}

we will be able to write -

try{
// Some code that throws ServiceException and WebsiteException
}
catch(WebsiteException | ServiceException exception) {
Logger.Log(exception);
throw ApplicationException(exception);
}

So, we will be able to get rid of duplicate exception handling code and will make our code little simpler. Its a pretty obvious change and ideally it should have been identified and fixed before.

This new feature is useful, but how much ? I think this is trying to solve the problem that should not exist. In most of the cases, you should not be throwing more than one checked exception.It will happen if we are exposing the implementation of method and rethrowing the exceptions from called methods.
Even if we have more than one exceptions, we may want to handle them in different ways. So we can not combine multiple catch blocks.
Apart from that, whole lot people in java devs community, including me, believes that checked exceptions should not be used at all. Checked exceptions forces developer to write the exception handling code even when it is not required. Exception handling code gets mixed up with the business logic. This leads to cluttered and unreadable code. Worst part is that checked exceptions create dependency between a method that throws exception and all other methods that directly or indirectly calls that. It makes caller of the method depends on the implementation details of the method. And after coding in C# (which doesn't have checked exceptions) for 2 years, i doubt whether checked exceptions are required in language at all.
Looks like this is nice to have but not so useful (lame?) features in Java 7.

Tuesday, March 24, 2009

Following SRP on grounds

Single responsibility principle is probably the simplest OO coding principle. It says "A class should have only one responsibility and thereby, only one reason to change." Isn't it very straightforward ?
But when I look at the code of my application, I see that very few classes in my app follows this principles. Why is that ? The principle is very simple and so it should be simple to implement as well. Its relatively easy to make sure that our class doesn't have any method that doesn't belong to the job of class. I think the difficult part is to know when we are adding additional responsibilities to the class. We do incremental development, start with only what is required and then add up behavior in methods and methods to class as required by the failing test. During this process, we somehow manage to sneak in the logic that is not the part of class's responsibility.
For example, we have mapper classes in our code which maps domain object to data contracts. The job of mapper classes is just to copy the fields from domain objects to contact. The mapper should only do this job of mapping. Consider the following example. In this, Booking object is loaded from the database. This class will map Booking to BookingData object.

public class BookingMapper{

public BookingData Map(Booking booking)
{
BookingData bookingData = new BookingData();
bookingData. Id = booking.Id;
// Other fields
bookingData.BookingFee = CalculateBookingFee (booking.StationCode, booking.TotalCost);

return bookingData;
}

private decimal CalculateBookingFee (StationCode stationCode, decimal totalCost){
// some complex logic to calculate booking fee based on station code and total cost,
// may be, the method will read some values from database.
}
}

The class BookingMapper has only one Map() method. From outside the class, it looks like the class has only one responsibility. However, apart from mapping the data, the class is also calculating the booking fee. It has 2 jobs - to map the data and to calculate the value of booking fee.

The mapper class should do only mapping and we have to move the responsibility of calculating booking fee to other class. If the fee calculation depends only on data present in booking object (like station code and total cost), then the obvious place for CalculateBookingFee method is Booking class itself. We can have a read-only property on Booking class called BookingFee which will calculate the fee.If the calculation of fee involves reading the values from database and/or from some other service, then we don't want our domain object to access services or database. In this case, we can calculate the booking fee (and any other required values) before invoking the mapper and pass it to Map() method. Either way, the fee calculation logic will move out of BookingMapper.

Sunday, March 22, 2009

Using extension methods

How many times you have seen your project having a StringUtils or a similar Helper class ? Most of the helper and util classes has pure procedural code. e.g StringUtils may contain a method IsNumaricString() or ToTitleCase( ) which takes a string as parameter.
Ideally all these methods should go in String class itself but we cann't extend String class as it is sealed. However, with the extension methods in C# 3.0, we can 'open' the classes and add methods to it.

So, instead of
string name = StringUtil.ToTitleCase("foo bar");
we can say -
"foo bar".ToTitleCase()

The extension method is defined as -

public static class StringX {
public static string ToTitleCase(this string str)
{
return string.IsNullOrEmpty(str) ? string.Empty : Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
}

The extension method is defined as a static method, in a static class. The first argument to the method is the type which we went to extend, preceded with 'this' modifier. When we call the extension method, we don't need to specify this first argument.
Isn't it neat ? The example I have used is the simplest one. There are many other cases when you can extend the functionality of the .Net system classes. Like, we can add Serialize() as the extension method in the Object class.

When I first came across this feature, I thought its the way to open classes in Ruby style. But well, its not exactly the same.
In extension method, we cann't access the private (or protected) members of the class that the method extends. We cann't use extension methods to override a method in the class.
The method defined in the actual type has precedence over the extension methods.So there is no way you can change the behavior of existing method with extension method.

One more good thing with extension methods is that they are available only on classes which refers to them. We need to import the classes that contains the extension methods.

The compiler translates the extension method call to the call on static method. So, its just a syntactic sugar to make your code look better. You cann't do 'effective' monkey patching with it as you cann't shadow a method defined in the actual type, neither you can access (and change the value of) any private member of the object.

However, we shouldn't use the extension methods haphazardly for extending the class behavior. Its definitely not the alternative for subclassing.

The MSDN says to use extension methods seriously and only when we have to. Well, my take is to use extension methods when its appropriate.
We can use it when its not possible or not appropriate to extend the class .e.g if we are using some class from the third party code.
Another best place to use extension methods is when you want to add a functionality to your data contract. Consider a scenario where you are getting a Booking object from some service. You want to check if the booking is valid based on some properties of the object. So your code will be something like this...

if(booking.BookingDate > DateTime.Now && booking.NumberofPassengers > 0 && booking.BookingCost > 1)
// then booking is valid

Here, we are accessing properties from the booking object to decide if the booking is valid. This is clear violation of "Tell, Don't Ask" principle (http://c2.com/cgi/wiki?TellDontAsk). The
best place for this logic is Booking class itself. But Booking is a data contract and we cann't add methods to it.So we can add an extension method IsValid() in a static class called
BookingX.

public static bool IsValid(this Booking booking){
return booking.BookingDate > DateTime.Now && booking.NumberofPassengers > 0 && booking.BookingCost > 1;
}

Now, by importing the BookingX class, instead of all the above code, we can say -
booking.IsValid()

So, extension methods helps you to keep the behavior in the correct class.