This is an AMP version of the article, its original content can be found here.
Singletons Must Die
I think it's too obvious to say that a singleton is an anti-pattern as there are tons of articles about that (singleton being an anti-pattern). However, more often than not, the question is how to define global things without a singleton; and the answer to that is not obvious for many of us. There are several examples: a database connection pool, a repository, a configuration map, etc. They all naturally seem to be "global"; but what do we do with them?
I assume you already know what a singleton is and why it's an anti-pattern. If not, I recommend you read this StackOverflow thread: What is so bad about singletons?
Now that we agree it's a bad deal, what do we do if we need to, let's say, have access to a database connection pool in many different places within the application? We simply need something like this:
Later in at, say, the JAX-RS REST method, we need to retrieve something from the database:
In case you're not familiar with JAX-RS, it's a simple MVC architecture,
text() method is a "controller". Additionally, I'm using
a simple JDBC wrapper from jcabi-jdbc.
We need that
Database.INSTANCE to be a singleton, right? We need it to
be globally available so that any MVC controller can have direct
access to it. Since we all understand and agree that a singleton is an evil
thing, what do we replace it with?
A dependency injection is the answer.
We need to make this database connection pool dependency of the controller
and ensure it's provided through a constructor. However, in this particular
case, for JAX-RS, we can't do it through a constructor thanks to its
ugly architecture. But we can create a
Database in its
and add that instance as an attribute of
servletContext. Then, inside
the controller, we retrieve the servlet context by adding the
annotation to a setter and using
on it. This is absolutely terrible and procedural, but it's better
than a singleton.
A proper object-oriented design would pass an instance of
to all objects that may need it through their constructors.
Nonetheless, what do we do if there are many dependencies? Do we make a 10-argument constructor? No, we don't. If our objects really need 10 dependencies to do their work, we need to break them down into smaller ones.
That's it. Forget about singletons; never use them. Turn them into dependencies
and pass them from object to object through the operator