views:

293

answers:

4

as a follow up on my previous question Having a function with combined generic bounds such as:

<T extends Foo & Bar> void doStuff(T argument) {
  //do stuff wich should only be done if arguments is both foo and bar
}

Because this is not castable from a unspecified object, you need to have knowledge of some object which actually implements these interfaces. it seems to me that needing to know the specific type of the object argument to pass to doStuff(T a) is a violation of Demeter's law.

The function doesn't specify the need to know the actual class (there could be many different ones), and i really don't want to know it as knowing this class increases the dependency in my code base.

is using these bounds an anti pattern? and if so how should one best avoid it?

the case scenario involved one interface specifying the object is persistent and the other specified object having a related entity. the doStuff(T a) function in this case persisted the related entity when it was persisted. however nonpersistent entities can also have a related entity, but should not be processed by the doStuff(T a) function

+1  A: 

I wouldn't consider combined generic bounds an anti-pattern. At least I've got some uses for them in my code. For instance, the following sample code finds the biggest Number instance in a collection using compareTo from the Comparable interface:

<T extends Number & Comparable<T>> T max(Collection<T> numbers)
Frank Grimm
Why does T need to extend Number? Does it not work work on any type that is completely ordered?
Hemal Pandya
Tom Hawtin - tackline
A: 

it seems to me that needing to know the specific type of the object argument to pass to doStuff(T a) is a violation of Demeter's law

I disagree. I don't see how

T<? extends Foo & Bar> void doStuff(T argument)

requires any more knowledge of argument to pass then

T<? extends Foo> void doStuff(T argument)

Or even more then just

void doStuff(T argument)

In all cases you need to know something about argument and I don't think the first cases is demanding any more knowledge then others because it has two identifiers.

Hemal Pandya
because in the first example we need to explicitly pass some class A implements Foo, bar, which means we need to know class A,while in the second example we only need to know the INTERFACE Foo (not the class B implements Foo)
pvgoddijn
A: 

The anti-pattern is casting.

However, fancy generics footwork may be confusing to non-advanced programmers. Usage of such types and method should be much easier than their implementation.

Tom Hawtin - tackline
A: 

This question seem related to the cast to combined generic question (by the same author).

Henrik Gustafsson
it is, but i thought it would be better for clarity to make this a different question
pvgoddijn
Well you knew all about it obviously, I was just thinking about everyone else who might want more context :)
Henrik Gustafsson