Showing posts with label design pattern example. Show all posts
Showing posts with label design pattern example. Show all posts

Wednesday, June 22, 2011

Exception transformer pattern

Checked exceptions are widespread in Java. Imagine the situation where you are calling numerous methods on a class (say for the sake of serving as an example: a service class) each of which throws a checked exception (say ServiceException).
class Service {

static class ServiceException extends Exception {}

void serviceMethod1() throws ServiceException {}
void serviceMethod2() throws ServiceException {}

}

Client with repetitive error handling logic
Your class as a client now has to deal with this exception every time you call a service method and also for every different method you call.
public class Client {

private Service service;

void callServiceMethod1Normally() {
try {
service.serviceMethod1();
} catch (ServiceException e) {
throw new RuntimeException("calling service method 1 failed", e);
}
}

void callServiceMethod2Normally() {
try {
service.serviceMethod2();
} catch (ServiceException e) {
throw new RuntimeException("calling service method 2 failed", e);
}
}

}


Exception transformer abstraction

However your exception handling strategy may be the same across your use of the service class only with a different message each time. Instead of repetitively duplicating your exception handling logic (try/catch) around every service call you can abstract this out as follows. The following class abstracts the logic out. Note that this class is only shown as a separate class for the purposes of incrementally describing the pattern. For best effect this class should ideally be contained within your client class as a static inner class.

public abstract class ExceptionTransformer {

abstract void call() throws ServiceException;

void transform(String message) {
try {
call();
} catch (ServiceException e) {
throw new RuntimeException(message, e);
}
}

}
New client using exception transformer

Now using the new exception transformer our exception handling logic is simplified to only the logic that differs between the client methods.

class ClientUsingExceptionTransformer {

private Service service;

void callServiceMethod1UsingTransformer() {
new ExceptionTransformer() {
@Override
void call() throws ServiceException {
service.serviceMethod1();
}
}.transform("calling service method 1 failed");
}

void callServiceMethod2UsingTransformer() {
new ExceptionTransformer() {
@Override
void call() throws ServiceException {
service.serviceMethod2();
}
}.transform("calling service method 2 failed");
}

}


Variation

This pattern can be easily varied to suit your personal exception handling styles. Here’s another variation where different checked exceptions are thrown by different service methods and handled by only logging them this time.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ClientWithVariations {

static final Logger logger = LoggerFactory.getLogger(ClientWithVariations.class);

static class Service {

static class ServiceHungry extends Exception {}
static class ServiceSleepy extends Exception {}

void hungryMethod() throws ServiceHungry {}
void sleepyMethod() throws ServiceSleepy {}

}

private Service service;

void callHungryMethod() {
new ExceptionTransformer() {
@Override
void call() throws Exception {
service.hungryMethod();
}
}.transform("method was too hungry to respond :(");
}

void callSleepyMethod() {
new ExceptionTransformer() {
@Override
void call() throws Exception {
service.sleepyMethod();
}
}.transform("method was too sleepy to respond :(");
}

static abstract class ExceptionTransformer {

abstract void call() throws Exception;

void transform(String message) {
try {
call();
} catch (Exception e) {
logger.error(message, e);
}
}

}

}

This pattern really shows its value most effectively when you have numerous methods using it and also when there are multiple checked exceptions to handle resulting in multiple catch blocks all over the place.
Do you have any exception handling API patterns of your own? I know Joshua Bloch has suggested a few in Effective Java of which one comes to mind – an exception throwing method can be transformed into a boolean via another method which just returns false in the catch block and true elsewhere that can be quite useful if you don’t want to pollute the rest of the code with knowledge of this handling logic. By the way, before anyone mentions this I’m not suggesting converting checked exceptions to runtime exceptions or suppressing them by logging them is always the right thing to do. Thanks for reading.
P.S. This pattern will be particularly nice with closures in Java 8. And the multicatch in Java 7 will certainly also help make code more concise.

Sunday, February 27, 2011

Factory pattern

Factory of what? Of classes. In simple words, if we have a super class and n sub-classes, and based on data provided, we have to return the object of one of the sub-classes, we use a factory pattern.
Let’s take an example to understand this pattern.
The Base class

public class Person {
// name string
public String name;
// gender : M or F
private String gender;

public String getName() {
return name;
}

public String getGender() {
return gender;
}
}// End of class
This is a simple class Person having methods for name and gender. Now, we will have two sub-classes, Male and Female which will print the welcome message on the screen.
Male.java

public class Male extends Person {
public Male(String fullName) {
System.out.println("Hello Mr. "+fullName);
}
}// End of class
Also, the class Female

public class Female extends Person {
public Female(String fullNname) {
System.out.println("Hello Ms. "+fullNname);
}
}// End of class
Now, we have to create a client, or a SalutationFactory which will return the welcome message depending on the data provided.


public class SalutationFactory {
public Person getPerson(String name, String gender) {
if (gender.equals("M"))
return new Male(name);
else if(gender.equals("F"))
return new Female(name);
else return null;
}
}// End of class


This class accepts two arguments from the system at runtime and prints the names.

Running the program:
FactoryPatternDemo.java


public class FactoryPatternDemo{
public static void main(String args[]) {
SalutationFactory factory = new SalutationFactory();
factory.getPerson("Kinshuk", "M");
}
}

The result returned is:

“Hello Mr. Kinshuk”.

When to use a Factory Pattern?


The Factory patterns can be used in following cases:
1. When a class does not know which class of objects it must create.
2. A class specifies its sub-classes to specify which objects to create.
3. In programmer’s language (very raw form), you can use factory pattern where you have to create an object of any one of sub-classes depending on the data provided.




Download source


You can download the source code of this program from here.