Parallel Hierarchies: Bad Design?

Just trying to find out if there is any consensus on this. Suppose I have an interface hierarchy three levels deep. In providing a default implementation for each, the class hierarchy is also three levels deep. In effect, there are two hierarchies, one for the interfaces and the other for the implementations. Is this a bad design smell? (I'm trying to reconcile coding to interfaces with inheritance of interfaces).

Thanks,

Saish

[451 byte] By [Saisha] at [2007-10-2 6:43:27]
# 1

> Just trying to find out if there is any consensus on

> this. Suppose I have an interface hierarchy three

> levels deep. In providing a default implementation

> for each, the class hierarchy is also three levels

> deep. In effect, there are two hierarchies, one for

> the interfaces and the other for the implementations.

> Is this a bad design smell? (I'm trying to

> o reconcile coding to interfaces with inheritance of

> interfaces).

>

> Thanks,

> Saish

Hi Saish,

Usually I would say yes, but in this case I think the answer is no.

As evidence, I'll offer the java.util Collections.

We have Collection->List on the interface side and AbstractCollection->AbstractList->ArrayList on the concrete side. Bad design? I don't think so. Joshua Bloch's intent was to code to interfaces (good idea - we agree) and provide convenient default implementations for each to the greatest extent possible.

I think that having parallel concrete hierarchies (e.g., DTO and EJB) is a bad idea, though. It's an anti-pattern that sprung out of the chatty traffic caused by entity EJBs. Better to stick with that single POJO, IMO.

%

duffymoa at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

> Just trying to find out if there is any consensus on

> this. Suppose I have an interface hierarchy three

> levels deep. In providing a default implementation

> for each, the class hierarchy is also three levels

> deep. In effect, there are two hierarchies, one for

> the interfaces and the other for the implementations.

> Is this a bad design smell? (I'm trying to

> o reconcile coding to interfaces with inheritance of

> interfaces).

>

> Thanks,

> Saish

No, it's good design smell. It's better to define type by an interface than it is a concrete implementation. The code is more flexible, different implementations can easily be substituded without painting yourself in to an inheritance corner. The heirarchies can feel redundant, but I don't think that's the case. The interface heirarchy defines type and the contract that type must adhere to. The implementation heirarchy is the actual implementation. By keeping them separate, you allow yourself to use the interfaces rather than the concrete implementations and give yourself the flexibility to change the implementation used without modifying the code that uses it.

Whether or not your heirarchy is too deep, too complex or taking on too much responsibility is another question entirely. Regardless, having parallel implementation and interface heirarchies is good design in most cases as far as I'm concerned.

kablaira at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

> > Just trying to find out if there is any consensus

> on

> > this. Suppose I have an interface hierarchy three

> > levels deep. In providing a default

> implementation

> > for each, the class hierarchy is also three levels

> > deep. In effect, there are two hierarchies, one

> for

> > the interfaces and the other for the

> implementations.

> > Is this a bad design smell? (I'm trying to

> > o reconcile coding to interfaces with inheritance

> of

> > interfaces).

> >

> > Thanks,

> > Saish

>

> Hi Saish,

>

Hey Duffy! Great to hear from ya! :^)

> Usually I would say yes, but in this case I think the

> answer is no.

>

> As evidence, I'll offer the java.util Collections.

>

> We have Collection->List on the interface side and

> AbstractCollection->AbstractList->ArrayList on the

> concrete side. Bad design? I don't think so.

> Joshua Bloch's intent was to code to interfaces

> s (good idea - we agree) and provide convenient

> default implementations for each to the greatest

> extent possible.

>

LOL! That was my inspiration for the hierarchy of interfaces, ironically enough.

> I think that having parallel concrete hierarchies

> (e.g., DTO and EJB) is a bad idea, though. It's an

> anti-pattern that sprung out of the chatty traffic

> caused by entity EJBs. Better to stick with that

> single POJO, IMO.

>

Totally agreed!

> %

Thanks Duffy,

Saish

Saisha at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> > Just trying to find out if there is any consensus

> on

> > this. Suppose I have an interface hierarchy three

> > levels deep. In providing a default

> implementation

> > for each, the class hierarchy is also three levels

> > deep. In effect, there are two hierarchies, one

> for

> > the interfaces and the other for the

> implementations.

> > Is this a bad design smell? (I'm trying to

> > o reconcile coding to interfaces with inheritance

> of

> > interfaces).

> >

> > Thanks,

> > Saish

>

> No, it's good design smell. It's better to define

> type by an interface than it is a concrete

> implementation. The code is more flexible, different

> implementations can easily be substituded without

> painting yourself in to an inheritance corner. The

> heirarchies can feel redundant, but I don't think

> that's the case. The interface heirarchy defines

> type and the contract that type must adhere to. The

> implementation heirarchy is the actual

> implementation. By keeping them separate, you allow

> yourself to use the interfaces rather than the

> concrete implementations and give yourself the

> flexibility to change the implementation used without

> modifying the code that uses it.

>

Whew! Glad to hear it. I also realized afterwards that the hierarchies need not be parallel. I could provide more or fewer implementations than the actual interface hierarchy provides. Which, IMO, seems to buy flexibility in the implementation.... usually a good thing.

> Whether or not your heirarchy is too deep, too

> complex or taking on too much responsibility is

> another question entirely. Regardless, having

> parallel implementation and interface heirarchies is

> good design in most cases as far as I'm

> concerned.

:^)

Thanks,

Saish

Saisha at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

I have been studying this situation for about 5 years now. It affects an application I have been working on so I always come back to this.

Its a tough choice wether to break down an interface into its smallest pieces giving flexibility in implementation, or to make the interface more whole giving ease of use of the interface.

What I found is that it has worked best to break down the interfaces into small pieces within a package, but the interface that leaves the package should be more whole and encompassing.

The interface heirachy does make it easier to make changes during development. For instance if you have INamedObject interface, and you want to add something you do it just on that one interface. As opposed to on 5 different interfaces that you want to all have the same properties. Eventhough INamedObject is never used anywhere except by the implementation. I think you can be purest and dump the INamedObject but it just ends with more work and no benefit I can see.

Actually I think my latest incantation has NamedObject only as part of the implementation and the INamedObject interface is dumped, lol.

Yea I guess I'm still going in circles on this one...

_dnoyeBa at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 6
In another forum in a land far far away, we discussed the ills of implementation inheritance. In the end I concluded that its not bad. What was bad was when implementation inheritance and interface inheritance were combined. But thats kind-of off topic.
_dnoyeBa at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

> What was bad was when implementation inheritance and interface inheritance were combined. But thats kind-of off topic.

Nay! That seems to be the original 'bad smell' I worried about. Not sure where I sit on this one either. Though, I do have some interface hierarchies. Spring Framework also has them, which is what got me thinking along these lines.

- Saish

Saisha at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> > What was bad was when implementation inheritance

> and interface inheritance were combined. But thats

> kind-of off topic.

>

> Nay! That seems to be the original 'bad smell' I

> worried about. Not sure where I sit on this one

> either. Though, I do have some interface

> hierarchies. Spring Framework also has them, which

> is what got me thinking along these lines.

>

> - Saish

Similar to another post I saw today asking why ArrayList implemented List if it already inherited List from the fact that it extended AbstractList. The idea is that AbstractList should not be passing List to its children, but let them describe what they are themselves. This makes AbstractList more dynamic since in fact AbstractList is really not a List quite yet. But in the long run it probably would be complicated to force this on folks. So we have the situation we have, where we add things like List when we technically don't have to.

_dnoyeBa at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

> Just trying to find out if there is any consensus on

> this. Suppose I have an interface hierarchy three

> levels deep. In providing a default implementation

> for each, the class hierarchy is also three levels

> deep. In effect, there are two hierarchies, one for

> the interfaces and the other for the implementations.

> Is this a bad design smell? (I'm trying to

> o reconcile coding to interfaces with inheritance of

> interfaces).

I don't think it's odd to have that many implementation levels. Whether they should all be public is a question but for me this is often about getting the most bang for my 'buck'.

I would be more concerned about all the inteface levels. Are all of these actually used in code? Do you have multiple implementations of each? The Collections interfaces have been mentioned, but how often do we actually use the Colletion interface explicitly? My answer is never. It could be removed and would not effect my code. It might effect code we use. However, I think a good case could be made that the Collection interface is pretty extraneous.

dubwaia at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 10
I will note, however, that interface heirachies are much more useful with covariance. Pre-covariance, they tend to be documentation only.
dubwaia at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> The Collections interfaces have been mentioned, but how

> often do we actually use the Colletion interface

> explicitly? My answer is never. It could be removed

> and would not effect my code. It might effect code

> we use. However, I think a good case could be made

> that the Collection interface is pretty extraneous.

I would completely disagree with this poster. I use the Collections interface everywhere I can. If it is reasonable to expect that a Set/List can be used, I will always use Collection.

The power of this is amazing. Imagine I am returning a collection of objects.

Collection getObjects()

The caller can choose to do one of 2 things

a) Iterate over it as is

b) Decide that a specific implementation might suit their needs better

SortedSet set = new TreeSet(getObjects()); // Sorted and unique

Set set = new HashSet(getObjects()); // Unique

List list = new ArrayList(getObjects()); // All objects

DASisk@yahoo.coma at 2007-7-16 13:51:53 > top of Java-index,Other Topics,Patterns & OO Design...