Sunday, December 9, 2007

Delegate using Dynamic Proxy

Java had the Dynamic proxy since 1.3. Somehow it is not a well known feature, maybe because the documentation is not so good. Of course there are some good articles written by Brian. Anyway I am going to show you how you can use Dynamic proxy to delegate easily.
First lets imagine you want to use the features of an existing class, but keeping good OO practices in mind, you decide to use delegation. Now the problem is you need to add lot of methods just for delegating to the actual class.
For eg, lets say you want to use the functionality of a List. You define your class and delegate to the actual List. It may look like this:

public class MyList implements List {
private List list;

public MyList() {
this.list = new ArrayList();
}

public void add(Object item) {
list.add(item);
}
//Similarly override all methods
}

This is not particularly interesting. Of course the IDEs help, but if the interface changes you need to add,recompile etc.

Enter Dynamic Proxy.

Simply put, there are two things you need to do to implement dynamic proxy. Create a Proxy (this sits between the user and your object. for eg. MyList) and create an InvocationHandler (This guy will intercept all methods and allows you to override at runtime).
Before we begin, the proxy creation method is not pretty so lets have a utility method that does that for us:

public static <T> T getProxy(Class<T> clazz, Object obj) {
    return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
            new Class[] { clazz },
            new Handler(obj));
    }

Now we will write the Handler (which is our InvocationHandler):

class Handler implements InvocationHandler {
    private Object obj;

    public Handler(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        try {
//Try the real object first (eg. MyList)
            Method m = obj.getClass().getMethod(methodName, method.getParameterTypes());
            return m.invoke(obj, args);
        } catch (NoSuchMethodException e) {
        }
        try {
//That failed. So try the underlying object (eg. ArrayList)
            Method m = method.getDeclaringClass().getMethod(methodName, method.getParameterTypes());
            Object delegator = obj.getClass().getMethod("getUnderlying").invoke(obj);
            return delegator.getClass().getMethod(methodName, method.getParameterTypes()).invoke(delegator, args);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Hmm, so what's going on here?
We intercept all calls to MyList and check whether it is implemented in MyList. If not, we will get the underlying object (For this we assume a method 'getUnderlying' is defined on the main class. Ideally this will be passed as argument) and invoke that. Simple isn't it?

Finally we don't even have to implement List. Our class will look like:

public class MyList {
    private List list;

    public MyList() {
        this.list = new ArrayList();
    }

//The methods specific to this class..
    public void addItem(Object item) {
        list.add(item);
    }

//Get the delegated object
    public Object getUnderlying() {
        return list;
    }
}

Ok, all that looks good, but how to use it?

List list = ListProxy.getProxy(List.class, new MyList());
list.add("a"); //add method of ArrayList
list.addItem("b"); //addItem method of MyList
println(list.size()); //size method of ArrayList -> prints 2

What have we done?
1. We used delegation without the pain of overriding all methods which have default behavior.
2. We used Duck typing (Though MyList does not implement List, we can use it as a List).
3. This code is generic and can be used for any interface/class delegation.

Thats all for now, folks!

Wednesday, November 14, 2007

Taking ideas from Ruby - 1

Ruby has gained popularity recently in dynamic language space. It does have some features which somehow appears elegant. Probably java can add some syntactic sugar, inspired by Ruby.
One small thing (but usually repeated one) is to test whether a Map contains an entry before adding items to it.
For eg:

Map myMap = getMap();
if (!myMap.contains("Count")) {
myMap.put("Count", 2);
}


Ruby has a ||= operator which does this checking implicitly.
With that the code will look like:

Map myMap = getMap();
myMap["Count"] ||= 2;

Thursday, October 25, 2007

PMD Plugin for IntelliJ Idea

I have written an update for the intelliJ plugin for PMD. Tom has mentioned about it in the pmd site. You can download it from Idea itself or from here. Read more about its features and start using it!

Sunday, October 21, 2007

new Boolean()

Java, for some strange reason had constructors for the Boolean object:
Boolean(boolean b) and Boolean(String s).
I could not think of any situation where this is useful (In fact the javadoc for the first form mentions it, but not the second). Consider the following:

Boolean b = new Boolean("true");
Boolean b1 = new Boolean(true);
Boolean b2 = Boolean.TRUE;

Now we have three object references, which are conceptually the same but not equal. Here, b == b1, b == b2 and b1 == b2 all result in false.

Looks like Auto boxing in 1.5 at least takes care of this, So if we have

Boolean b1 = true;
Boolean b2 = Boolean.TRUE;

b1 == b2 is indeed true. (Boolean.valueOf() methods had no problem anyway)

btw, a Boolean can be thought of as an example of a Flyweight.