user1870400
user1870400

Reputation: 6364

what design pattern can I use to create an object that implements a specific interface or multiple or any combination among the available interfaces?

what design pattern can I use to create an object that implements a specific interface or multiple or any combination among the available interfaces? for Example say I have the following

interface A {
   void foo();
}

interface B {
   void bar();
}

interface C {
   void car();
}

class Agent {

}

I want to be able to say give me object of class Agent that implements interface A?

or

I want to be able to say give me object of class Agent that implements interfaces B?

or

I want to be able to say give me object of class Agent that implements interfaces C?

or

I want to be able to say give me object of class Agent that implements interfaces A,B?

or

I want to be able to say give me object of class Agent that implements interfaces B,C?

or

I want to be able to say give me object of class Agent that implements interfaces A,C?

or

I want to be able to say give me object of class Agent that implements interfaces A,B,C?

or

In general what I am looking for is to create an object which can have the functionality from any combination of interfaces.

Upvotes: 0

Views: 288

Answers (3)

Piacenti
Piacenti

Reputation: 1218

What you want as a Java Proxy. You are not really providing a reason for why you need that but I can provide one I've had previously. When dealing with widely variable data you may end up needing to do something like duck typing. If this thing has a tail property you may want to add a HasTail interface to it. If those objects are not predictable upfront and they have many similar properties of interest where you want to apply some sort of interface to it for the purposes of type checking later on like you indicated, a Proxy object lets you do just that.

InvocationHandler handler = new MyInvocationHandler(...);
Class<?>[] applicableInterfaces = determineApplicableInterfaces(...);
//let's say Foo is one of them (maybe a common interface always applied) or you can simply just leave it as Object
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          applicableInterfaces,
                                          handler);

This solves the problem of having to create a plethora of objects with all possible combinations of those interfaces where large portions of them may or may never happen in practice.

Upvotes: 0

Gulllie
Gulllie

Reputation: 558

The best solution I can think of would be to have Agent implement all of your interfaces, then to use it as needed with your desired interface, such as:

A agentUsingA = new Agent();

You would then only be able to call the methods implementedfrom A.

However:

This is a really bad way of using interfaces. One of the main ideas of an interface in java is to act as a sort of "contract". For example:

Say you have two classes: AEncryptor and BEncryptor. Both of these classes implement the interface EncryptService, which has the method .encrypt(String text).

So, say you have a method somewhere called encryptString(EncryptService service, String textToBeEncrypted). This method takes an encrypting service and uses it to encrypt the string textToBeEncrypted. All this method will do is call service.encrypt(textToBeEncrypted);

Now, encryptString() dosen't care how service will encrypt the string, all it knows is that when it calls .encrypt(textToBeEncrypted) on it, it will encrypt the text.

So AEncryptor and BEncryptor could encrypt the text completely differently, but because they implement EncryptService, we know that it's encrypt method will be there, and that by calling it, it will encrypt the text.

In you're example, we won't really know what we can call on Agent, we wont have any assurance that a method (Say, .encrypt()) will actually be there.

For more information on interfaces, have a look into Oracle tutorials here and here. ;)

Upvotes: 1

sprinter
sprinter

Reputation: 27966

Java is a statically typed language (see this question for details). This means that a variable you describe has a type which includes a set of interfaces that are implemented. So it does not make a lot of sense to say that you want an object of a certain class to vary the interfaces it implements.

Having said that, I suspect you are trying to use interface for something for which it is not intended. For example if you want a class whose objects can have various capabilities that are determined when the object is created then there are design patterns that might work for you.

Without knowing your needs it's hard to suggest specifics but here's a possible model:

interface A {
    void foo();
}

interface B {
    void bar();
}

class Agent {
    private Optional<A> delegateA = Optional.empty();
    private Optional<B> delegateB = Optional.empty();

    public void addA(A delegate) {
        delegateA = Optional.of(delegate);
    }

    public boolean implementsA() {
        return delegateA.isPresent();
    }

    public void foo() {
        delegateA.ifPresent(A::foo);
    }
}

Agent agent = new Agent();
agent.addA(() -> System.out.println("foo"));
agent.implementsA();
agent.foo();

Upvotes: 3

Related Questions