Recently I interviewed a couple of folks. One of the guys was a C++ guy and I thought of delving into the tricky and interesting land of function pointers with him. This is when the question in the title occurred to me : How would you implement callbacks in Java?

Its nothing new, its nothing great, but I was just curious how the candidate would apply his language feature proficiency to implement a real world problem. I asked that question to that candidate and two more, after which I thought I should write this post. None of the three candidates knew how to do it. Worse one of them was completely bewildered and was like "what are you trying to say???". Damn it!!! :(.

Well here is my take on implementing Callbacks in Java. Hope you find it useful.

What are callbacks?
A callback is a paradigm by which a general purpose library can delegate (generally domain specific) parts of its execution to an external, more appropriate owner. This fits well with the "separation of concerns"process - your code will do just the work it understands.

A classic example is the sort functionality - references are available in C++, Java and other languages. The sort method, typically, would accept the list of objects to be sorted, along with an optional callback for object comparison. The sort method (the general purpose library) knows how to sort lists very well, but does not need to know the algorithm to decide the ordering of two given data objects (comparison of data objects). Since comparison of the data object (your domain specific decision) is an important part of the sorting algorithm, the sort method will allow you to specify a function that it can call when it needs to compare two of your data objects. This function is the callback.

Why the fuss?
Callbacks are great! They are means available for developers to write layers of generic code that is reusable across domains with a minimal overhead. We most certainly use callback in our day-to-day code, probably without realizing them (hence those 3 candidates). Callbacks are the backbone for various implementations - lifecycle listeners (in containers), Spring (HibernateTemplate, JdbcTemplate and more), Collections.sort(), .... the list goes on.

Nice. How are they implemented in Java?
Lets just think about it - what is the callback specifying? Its allowing the caller to specify the method to be called from the method to-be-called. This could mean, at least, two things - either the method to-be-called is given the exact callback method (within an instance / global context) OR the method to-be-called declares that it would call a specific method name with specific parameters (on the callback being passed) and its the responsibility of the caller to ensure that such a method exists in the callback object's context.

While the first approach is possible in languages like C++, the second approach fits the Java world. Another read of the second approach tells us that what we taking about is a contract - a binding that the caller must confirm to, which the method to-be-called can rely on.

In Java, how are contracts specified?? Well - by using interfaces. If the method to-be-called accepts an instance of an interface, as its callback parameter, then it will enforce the caller to implement an object that implements the methods from that interface. The method to-be-called should, however, declare beforehand which methods from the interface it would calls from within its code at what time (the contact of the methods).

3 comments:

i m surprised you did not mention observer patterns, I guess if you want callbacks type functionality Observer pattern is the way to go.IMHO command pattern should not be implemented for callbacks, command pattern is for places where you need orders from some entity. In callbacks, you are just interested in observing some events (pre/post), so observer pattern is a better fit to implement callbacks in Java.Regarding the object comparison in sorting example, I guess strategy pattern is suited more for its design, as you are outsourcing the strategy of comparing two objects. Please do correct me if I am wrong.

Agree Bhavin, the Observer pattern is another example that is implemented using callbacks. Note that "callbacks" are used to implement the pattern - not the other way round :)

About the strategy pattern - I think this pattern is more to decide at runtime what algorithm you want to use. So as a "sort" analogy, I think the fact that Java allows you to implement custom equals/hashcode is the strategy pattern.

That however, is still distinct from the callback. The callback is the part where the "sort" method will delegate the "compare" call to you.