[Biojava-dev] Singletons are bad

Mark Schreiber markjschreiber at gmail.com
Tue Jun 30 08:33:28 UTC 2009


I came across this today which is an interesting article about how
singletons seem like a good idea but after a while you realise they get you
into serious trouble. After playing with BioJava for over 10 years I
completely concur. Singletons and fly-weight objects are (IMHO) the most
serious problem in the BioJava code base and as the article predicts the BJ
code base is completely infected with them.

The article is here:
http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/


But I have copied the paragraph below as it seems to offer a way out without
completely breaking everything.  This should be seriously considered for
future BJ releases.

... paste starts here
But I already have a bunch of singletons in my code!

Sometimes, you’ll have a system (built by you or someone else) that is
heavily dependent on some singletons. Often, you will find this annoying as
you try to test and/or add functionality to the system. To refactor the
singletons out of your system, you need to start from each point of use and
allow the singleton to be set as a dependency on the component using it,
rather than calling to the singleton’s getInstance() method. Doing so moves
the singleton access (but not use) up one level. Repeat until the
singleton’s getInstance() method is called in as few places as possible
(ideally one).

At this point, all components in the system declare their dependence on the
concrete singleton class and that singleton class is instantiated at a very
few points at the “top” or your architecture (then passed down through the
systems). Next, it’s time to apply some classic refactoring. Most
importantly, we want to change the concrete singleton class into an
interface and move the existing concrete implementation into a new default
implementation class implementing the interface. Finally, you’ll probably
want to cleanup the calls to getInstance() with either a call to new the
concrete default implementation or a factory method that can do that for
you.

This transformation should make all of your components dependent on an
injectable, interface-defined component, which is easy to mock or swap in
during unit testing of the component itself. It also typically makes testing
of the concrete singleton implementation itself a breeze compared to the
prior implementation.

Note that the first phase of bubbling the singleton instantiation up through
the architecture can be done as slowly as needed and does not need to be
done all at once. You’ll find the second phase is fairly easy with any
modern IDE once you get to that point.




More information about the biojava-dev mailing list