//
you're reading...
General, Java/Cloud

Multiple Inheritance and java

Recently I got myself again into a situation where I have hit the wall with java’s limitations on inheritance, i.e., no scope for multiple inheritance. I have read a lot of websites which give reasons for java not having multiple inheritance. I am well aware of the proposed interface and delegation pattern instead of multiple inheritance. But, IMHO, there exists situations which demand multiple inheritance instead of delegation.
Describing the problem:
Consider the following scenario. I want to write a pool framework that can pool any set of objects and provide a no-lock pooling. To do this say I want to do something as below:
public class ObjectPool
{
    private AtomicReference _head = new AtomicReference();
      …..
    public PooledObject acquire()
        throws EFException
    {
        int tries = 0;
        int retryacquired = 0;
        while (true)
        {
            PooledObject acquired = _head.get();
                         …….
            if (_head.compareAndSet(acquired, acquired.next()))
            {
                acquired.setNext(null);
                _currentFreeSize.decrementAndGet();
                return acquired;
            }
        }
        return null;
    }
}
This requires that any object that is pooled implements the PooledObject interface which has a setNext and next functions in it. But seeing the logic more carefully it becomes apparent that these two functions don’t vary by a specific object and is a necessity because of the logic and can be provided as a standard implementation. Say we can write a PooledObjectImpl as below:
public class PooledObjectImpl implements PooledObject
{    
    transient PooledObject _pool$$next; 
        public PooledObject next() { return _pool$$next; }    
    public void setNext(PooledObject obj) { _pool$$next = obj; }
}
Here it becomes necessary that the objects derive from this PooledObjectImpl class to use the framework.
Let’s now try to use this for a pool application such as pooling communication channels. Now this has a pattern in itself where we can have communication via http, or via proprietary protocol. So we have a class which needs to be similar to:
public class HttpCommunication
{
    Channel _httpChannel;
    …….
    public void sendResponse(Object obj)
    {
           HttpResponse rep = new HttpResponse(HTTP_OK);
           ………..
           rep.setContent(formatPayload(obj));
           channel.write(rep);
    }
}
public class MyCommunication extends HttpCommunication
{
    ….
    protected String formatPayload(Object payload)
   {
        //create a json payload from the object
   }
}
Now we have hit a block, how do we pool MyCommunication object? MyCommunication is basically a HttpCommunication object as well as a pooledobject, how do we do this in java now?
Currently possible solutions:
The standard solutions I have seen implemented to overcome multiple inheritance requirements:
Option 1: Hierarchy derivation
We make HttpCommunication extend PooledObjectImpl. Disadvantages of this:
  • Any communication object by default becomes poolable. 
  • There is no question of being able to pool or not pool based on requirement. This can be done by not calling the ObjectPool at all. But this implies that unnecessary code is lying around in objects.
Option 2: Delegation Model
We make MyCommunication implement PooledObject interface, embed a new PooledObjectIImpl in MyCommunication, and implement the PooledObject interface functions to delegate the functionality to the attribute. Something as below:
public class MyCommunication extends HttpCommunication implements PooledObject
{
    private PooledObjectImpl _impl;
    ….
    protected String formatPayload(Object payload)
   {
        //create a json payload from the object
   }
        public PooledObject next() { return _impl.next(); }    
    public void setNext(PooledObject obj) { _impl.setNext(obj); }
}
Major disadvantages of this:
  • Maintenance nightmare. If the PooledObject interface were to change all the classes that use this pattern has to be changed to implement and delegate the function to the contained implementation class.
More appropriate solutions:
My suggestions to overcome some of the disadvantages of the above solutions:
Option 3: Changing implementation
In this approach we still delegate, but we delegate the whole functionality instead of individual functions. What does this mean? Say we did the below instead of the above:
public class MyCommunication extends HttpCommunication implements Poolable
{
    private PooledObjectImpl _impl;
    ….
    protected String formatPayload(Object payload)
   {
        //create a json payload from the object
   }
        public PooledObject myPoolImpl() { return _impl; }
}
Here we have introduced a new interface called Poolable, what does this imply, that 
             “I provide pool-able functionality using PooledObjectImpl”
The Poolable interface is as below:
public interface Poolable
{
    PooledObject myPoolImpl();
}
So, if this is the implementation, our ObjectPool needs to be implemented as below:
public class ObjectPool
{
    private AtomicReference _head = new AtomicReference();
      …..
    public Poolable acquire()
        throws EFException
    {
        int tries = 0;
        int retryacquired = 0;
        while (true)
        {
            Poolable acquired = _head.get();
                         …….
            if (_head.compareAndSet(acquired, acquired.myPoolImpl().next()))
            {
                acquired.myPoolImpl().setNext(null);
                _currentFreeSize.decrementAndGet();
                return acquired;
            }
        }
        return null;
    }
}
The disadvantage of the delegation model is overcome, since the implementation requirement for ObjectPool  is separated out from the actual object, and add delegation is of a functionality instead of individual functions.
This does require a rethink in terms of how the functionality is implemented, but this decreases maintenance nightmare that is created where multiple objects have to be changed when the implementation of the pool is changed.
Option 4: Templating or Stereo Typing
The above is a more simpler solution where code using the framework has to still be changed to implement interfaces. A more elegant solution would be if we could BCI the code during load time with the functions and fields of the PooledObjectImpl class. This can be easily achieved using the ASM libraries. (Refer: ASM Library)
This overcomes all disadvantages of the previous approaches and provides many more advantages such as:
  • Enable Pooling only if the pooling module is enabled, this can be done by BCI’ing only when Pool Modules is loaded.
  • Adding new functions or changing implementations implies just a change to the template or stereo type which is added to the object.
  • More than one functionality “ableness” can be added without changing the object, so the same MyCommunication object can become a “Poolable” object, a “Debuggable” object etc without any changes to the object implementation.
But this does have a major disadvantage that all classes have to be loaded using your classloader which does the BCI.

About these ads

Discussion

2 thoughts on “Multiple Inheritance and java

  1. Good one. Third solution (option 3) is something new I found here.

    Posted by Ravi Prakash Reddy | June 1, 2012, 7:35 am

Trackbacks/Pingbacks

  1. Pingback: HOW TO: Stereotyping a java Class | Reflections - July 20, 2013

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 145 other followers

%d bloggers like this: