Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java OO: Is this even possible?

Tags:

java

oop

I'm trying to hide an implementation of a class I do not own. I'm wanting to do this my extending the class and implementing an interface of my own. Here is how an instance of the class I need is created:

QueueInfo info = admin.getQueue(queueName);

QueueInfo is the class I do not own. To get an instance of this object, I have to use an admin object to get it. I am wanting to hide this implementation by working through an interface called IQueueInfo. IQueueInfo will just give access to what consumers need from QueueInfo. So to get at this QueueInfo, I would like work through my own object called EMSQueueInfo. Here is how I envision setting this up:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo {
    //...
}

This allows my consumer to work though the interface IQueueInfo and it allows the underlying EMSQueueInfo to have access to everything QueueInfo has. My problem lies with getting a "live" instance of QueueInfo. To get a regular instance of QueueInfo, I could just say:

QueueInfo info = new QueueInfo(queueName);

This instance is not "live" as in it was not created by the admin object. So, doing this:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo {

    public EMSQueueInfo(String queueName){
        super(queueName);
    }

}

does not give me a "live" object. What I would love to be able to do is something like this:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo {

    public EMSQueueInfo(String queueName, Admin admin){
        super = admin.getQueue(queueName);
    }

}

But that is impossible.

The only solution I'm seeing is removing the extends from my EMSQueueInfo class and just wrapping the object up myself, getting access to all of the methods via a private varialbe:

public class EMSQueueInfo extends QueueInfo implements IQueueInfo {

    private QueueInfo _queueInfo

    public EMSQueueInfo(String queueName, Admin admin){
        _queueInfo = admin.getQueue(queueName);
    }

    public int getMessagesOnQueue() {
        return _queueInfo.getMessagesOnQueue();
    }

}

That solution does work, but I kind of hate it. Can anyone think of a better way? Am I just trying to break OO and misuse it? Again, I'm only doing all of this because I want consumers to be able to work with IQueueInfo, in the future, IQueueInfo could be used to access a JMS implementation of QueueInfo or an MSMQ implementation of QueueInfo. Any help would be amazing!

like image 557
Tyler Wright Avatar asked Feb 15 '13 13:02

Tyler Wright


2 Answers

I believe the solution you are using that you say you hate is a good solution. It does not break OO or misuse it.

What you are doing is well known pattern called Adapter pattern (Object Adapter pattern). Only thing that is not needed in your class is extending the QueueInfo.

like image 105
Martinsos Avatar answered Oct 07 '22 02:10

Martinsos


What you have suggested seems perfectly reasonable - it's called the adaptor pattern (thanks Martinsos).

It would be nicer if you can hide the Admin object within your class somehow. E.g.

public class EMSQueueInfo implements QueueInfoProvider {

    private static Admin admin = new Admin();
    private QueueInfo queueInfo

    public EMSQueueInfo(String queueName){
        queueInfo = admin.getQueue(queueName);
    }

    public int getMessagesOnQueue() {
        return queueInfo.getMessagesOnQueue();
    }

}

I tried to give your interface a more "Java" name. The I suffix is very .NET. There should be no need to extend the original class.

It can feel painful to implement as you have to laboriously copy only the interesting methods from QueueInfo into your QueueInfoProvider, but the pain will be worth it in the end.

This approach decouples your application from an API you have no direct control over. In that sense, it is similar to the Facade pattern.

like image 23
Duncan Jones Avatar answered Oct 07 '22 01:10

Duncan Jones