Having methods in a Java object that you will never invoke is a pretty
obvious Design Smell. It’s already hard to keep the complexity of your
objects in check when you limit yourself to strict business logic, so why would
you add these useless methods on top of it?
Well, it’s actually quite common in Java programming. So common that
you probably add such methods every day to your classes without even realizing
Some examples: HttlServlet.doPost(), JMSListener.onMessage(),
Dependency injection is also a big offender in this area: setter
injection forces you to implement setters you will never invoke, and constructor
injection makes you modify the signature of your constructors (which is even
more intrusive in my opinion).
Alright, at this point you are probably rolling your eyes and dozens of
objections are coming to your mind. Fair enough, I agree that most of
these methods actually provide important connection points between the container
and your object. When these methods are invoked, you are given a chance to
execute some logic that can be very important to your application.
As a matter of fact, all the methods I have just mentioned enable this.
All of them except… setter injection.
Setter injection is a way for the container to hand you some objects so you
can store them and reuse them later. The problem is, it’s not the setter
you are interested in, but the getter. The typical implementations of an
injected setter is to store the value in a field for later use. You don’t
get more boiler-plate than this.
There are three ways to look at this problem:
- It’s only a one-line method, it’s not a big deal.
- Since the setter is useless, have the container perform field injection
(possibly tagged by an @ContainerProvided annotation).
- Let the container implement the getter.
I wish there were one simple answer, but unfortunately, these three
approaches all have pros and cons. The one-line method can be seen as
needlessly polluting your POJO class. Field injection is a little less
invasive but I’m not sure I like the idea that the container is messing with
private parts of my object. Finally, solution 3 sounds like the ideal
solution (no pollution, no messing with private fields) but it requires either
abstract methods or objects whose bytecode has been tweaked by the container,
both of which make testability harder.