1

Motivation

Let a project where...

... exists a lot different behaviors. For each behavior, there is an interface which has its possible actions. One object could perform a lot different behaviors.

Normally, a collaborator "A" only cares about interface "I" from a specific object.

So, how to avoid a object to implements lot of roles.

Example:

public class MyComplexObject implements Closeable, Reliable, Trustable, Treable, Moveable { ...}

Why bother?

Composition solves the problem. But only partially. In Java, the target object will still have to delegate the problem calls for the target implementation. Although it is no-brain implementation, it is not comfortable when the list of roles is more than 5.

Inheritance (over interfaces) will not turn things better.

Let's assume 6 different interfaces (each interface with 5 methods). For now, let us simplify and imagine a default implementation for those interfaces. Now, assume that a set of more complex objects could implement one to six of those interfaces. It means 2^6= 64 different possible combinations. Also, long list of interface means a long list of internal methods.

It is clear that inheritance, using a BaseImplementation, does not make sense in this case.

Examples:

public class MyComplexObject1 implements Closeable, Reliable, Trustable, Treable, Moveable { ...}
public class MyComplexObject2 implements Reliable, Treable, Moveable { ...}
public class MyComplexObject3 implements Reliable, Trustable, Moveable { ...}
public class MyComplexObject4 implements Closeable, Trustable, Treable { ...}

I am not asking for a silver bullet

"Being skeptical", "avoiding complexity" of course, those thing are good. However, too general. This problem is when long list of roles hurts. So this is a corner case scenario and not a mainstream problem.

What does not mean unrealistic scenario. There is a project that use an idea that could be used to solve that problem.

Netbeans, that has the concept of cookies

EditorCookie ec = activatedNodes[0].getLookup().lookup(EditorCookie.class);

A cookie is a capability and cookies are a powerful feature of NetBeans. With a Java interface, your object's capabilities are fixed at compile time, while NetBeans cookies allow your object to behave dynamically because your object can expose capabilities, or not, based on its state.

https://platform.netbeans.org/tutorials/60/nbm-porting-basic.html

How cookies-like could be implemented

public class MyComplexObject { 
    private Map<Class<?>, ?> adapters;

    public <T> T getAdapterIfApplicable(Class<T> t){
       return (T) adapters.get(t);
    }
    public MyComplexObject add(Class<T> aClass, T t){
       adapters(aClass, t);
       t.setTarget(this);
    }
...
}
...
public CloseableAdapter implements Adapter{
    void setTarget(Object target){
        this.target = target; 
    }
}
...
new MyComplexObject().add(CloseableAdapter.class, aCloseAdapter);    
  • 2
    What do you mean by "adapter for that interface"? A helper class which holds an instance of MyComplexObject and implements the desired interface, as in en.wikipedia.org/wiki/Adapter_pattern#Object_Adapter_pattern? If so, how are you going to specify the adapter type in getAdapterIfAppliable? And how will you distinguish between different adapters if there is more than one that fits? – Doc Brown May 26 '15 at 18:58
  • 4
    This approach allows you to configure the available adapters for each instance of MyComplexObject individually. Is that flexibility really what you need? Seems it will come for the cost of a lot of additional overhead, in code to maintain, in memory for each object, and maybe in running time. If you do not need really the flexibility, you are at risk of overengineering things. – Doc Brown May 26 '15 at 20:28
  • 3
    ... how to avoid a object to implements a long list of interfaces. ... Why do you see this as a problem? – Jarrod Roberson May 26 '15 at 22:32
  • 2
    It's Java, it's supposed to be obscenely verbose. – msw May 27 '15 at 2:41
  • 3
    @rdllopes - your question is an X-Y Problem, where Y is this Adapter Pattern solution and you are asking if it is a good design, when you need to be asking what others have done, it is not this Adapter Pattern approach. – Jarrod Roberson May 27 '15 at 13:45
9

It appears from the comments and edits that your concern is more about duplicating code in multiple implementation classes. That has nothing to do with how many interfaces are implemented.

Composite Pattern with Delegation

If the implementations of each interface is generic then they should be classes that are delegated to using the Composite Pattern. The adapter pattern is not the solution either way.

If A implements C then A is a C. To burden the calling code with this obfuscation of Adapter Pattern is a terrible API decision.

The question you are asking is not the correct one:

... how to avoid a object to implements a long list of interfaces.

I think you are seeing a problem that only exists to you. I have worked on hundreds of millions of lines of Java code since 1995. I have never seen the problem you seem to be concerned about.

The number of combinations of interfaces is not a practical issue. Never has been. If you have too many interfaces with to many methods then that is a design problem that needs to be fixed, your solution is not that fix.

You are adding a ridiculous amount of complexity for no apparent benefit:

implements means what is implementing that interface is a relationship, that is pretty tightly coupled and introducing Adapter pattern type indirection is going to bloat the codebase with more complexity and code to maintain and test, which is a good enough reason to not do that.

If this was a good approach it would have been done half a dozen times as an opensource library the 20 years that Java has been around.

This Adapter Pattern you are trying to use is not the correct approach, it will create a heavy burdensome API and be extremely brittle.

The work to use the API will be orders of magnitude more effort than maintaining naively duplicated code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.