What criteria should be used when deciding between:
Suppose I have:
interface FooLoader {
Foo loadById(long id);
}
class DBFooLoader implements FooLoader {
... jdbc etc. etc. ...
}
class CachingFooLoader implements FooLoader {
...
@Inject
public CachingFooLoader(FooLoader delegate) {
this.delegate = delegate;
}
...
}
Suppose I want to bind FooLoader
to CachingFooLoader
, I have [at least] two ways to wire this:
Change:
public CachingFooLoader(FooLoader delegate)
to:
public CachingFooLoader(@NonCaching FooLoader delegate)
and then:
bind(FooLoader.class).annotatedWith(NonCaching.class).to(DBFooLoader.class);
Change:
public CachingFooLoader(FooLoader delegate)
to:
public CachingFooLoader(NonCachingFooLoader delegate)
where NonCachingFooLoader
simply extends FooLoader
, and then have DBFooLoader
implement NonCachingFooLoader
, and wire up accordingly.
I am drawn to using an annotation binding for multiple reasons:
However, creating a more specific interface has its advantages too:
So, what criteria should be used to determine which approach to take?
(Spring users, as far as I can tell, this is what you guys call qualifiers.)
Use specific interfaces only if it makes sense, i.e. they have to offer a different API and thus other classes will use them in a specific way.
If they offer the same "service" in different ways, then use only one common interface and differentiate implementations with annotations.