Source (reposted here as it's hard for me to read on that page)
Single(ton), again.
Who
among us hasn't smuggled into the break-room to nibble on a Singleton
newton? I, like you, drank the Singleton kool-aid. At first Singletons
were used appropriately. Then, they were used inappropriately. Then they
were used really inappropriately.
And somewhere between the appropriate and the inappropriate, you, like
me, probably realized that something was amiss. Something was aloof, a
little bit off.
Then I, like you, read "Singletons Considered Stupid" by Steve Yeggee:
Why is the Singleton so attractive? I'll be the first to admit: I liked it too. No, scratch that – I loved the Singleton. It felt like an old friend from the moment I laid eyes on it. It was simple and beautiful.I'll tell you why: it's because the Singleton pattern is a throwback to non-OO programming. It's a lifeline for people who didn't understand a single word that the Gang of Four were trying to say. It's almost exactly the way I programmed back when I didn't know jack squat about OOP. The only significant difference is that instead of having a file with a bunch of global functions in it, I have a file with a CLASS that has a bunch of global functions. No need to worry my little head about how many of them to have, since you only need one! It's OOP made easy.
And my heart was broken.
I learned that Singletons were actually referred to as something called a "code smell." I didn't know if the smell was good or bad, but we figured it was bad.
I learned that Singletons violated something called the 'Single Responsibility Principle'
which states that every class you create should do one thing and one
thing only because a Singleton has two distinct responsibilities:
policing the instances of itself and providing configuration
information.
I
learned that Singletons were bad for memory management. If no one uses
it for awhile, its just going to sit and twiddle its thumbs.
I
learned that the state of the Singleton never goes away. Persistent
state is the enemy of unit testing. One of the things that makes unit
testing effective is that each test has to be independent of all the
others.
I
learned that Singleton's are kind of impossible to sub-class because
they are static methods and static methods are about "as flexible as
granite."
I
learned that Singletons are (mostly) used as glorified globals and if
you use them in your project, your project becomes almost impossible to
unit-test because your "objects can secretly get hold of things which
are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars." Basically, when objects use Singletons they hide their dependencies.
I
learned that maybe, just maybe you'll realize somewhere down the line
that you actually need TWO instances of the Singleton. Then what, buddy?
So
I did what any completely sane Programmer would do. I ripped RIPPED the
Singleton Pattern out of GOF and burned the pages while doing a triple
hail mary and beat on, boat against the current, swearing never NEVER to
use another Singleton for as long as I shall live.
Then,
three weeks later, after I sobered up, I realized that all the stuff I
learned about why Singletons were the devil incarnate was actually a
form of "abstinence only" Design Pattern Education. I knew that I could
avoid all the aforementioned problems by simply abstaining completely
from using Singletons, but what I didn't know was what happened on the
day when I wanted to use a single instance of a class and thought that
the Singleton might be the best tool for the job?
Fine. Go ahead, use it.
First, before I answers the question posed above, let me address you.
I know you. You're stubborn. You're going to use that Singleton until
someone rips it from your cold, dead claws. If this is you, then just
read on a little while longer then you can get back to uploading your
favorite programming cartoon to stackoverflow.
If you do use Singletons, try to use dependency injection instead of calling getInstance() from the constructor.
Use this:
rather than this:
At
the very least, using dependency injection allows you to do some unit
testing of the class by adhering to good encapsulation principles. Using
dependency injection might also stop Misko Hevrey from calling your APIa pathological liar. But probably not.
Check yo-self.
For all the rest of you still reading, before using a Singleton ask yourself, "is a Singleton really the best tool for the job?"
On my quest for the truth I discovered that there are actually very few "acceptable" reasons to use a Singleton.
One
reason that tends to come up over and over again on the internets is
that of a "logging" class. In this case, a Singleton can be used instead
of a single instance of a class because
a logging class usually needs to be used over and over again ad nauseam
by every class in a project. If every class uses this logging class,
dependency injection becomes cumbersome.
Logging
is a specific example an "acceptable" Singleton because it doesn't
affect the execution of your code. Disable logging, code execution
remains the same. Enable it, same same. Misko puts it in the following
way inRoot Cause of Singletons,
"The information here flows one way: From your application into the
logger. Even though loggers are global state, since no information flows
from loggers into your application, loggers are acceptable."
I'm sure there are other valid reasons as well. Alex Miller, in "Patterns I Hate", talks of service locators and client side UI's also being possibly "acceptable" choices.
Single Instance Of A Class
In
most cases, though, you probably got it wrong when you went to the ole'
Singleton toolbox. What you probably wanted was a simple single instance of a class instead
of a Singleton. There is absolutely nothing wrong with only wanting a
single instance of a class. There are, however, way better ways of
managing these instances then a "glorified global".
How
do you achieve a Single Configuration Object without using a Singleton?
Neal Ford in "The Productive Programmer" suggests "using a plain object
plus a factory and delegating the individual responsibilities to each.
The factory is responsible for the instance policing and the plain
object deals only with configuration information and behavior." By using
this technique, your code no longer smells as it now adheres to theSingle Responsibility Principle.
Misko
Hevrey (who does testing for google) goes into much greater detail
about this technique in his two fantastic blog posts entitled "How to Think About the 'new' Operator with Respect to Unit Testing" and "Where Have All the Singletons Gone?"
The idea is to have either classes with logic or classes with the new operator (factories). When you need a single instance of a logic class,
you call on the factory to build that class. Using this technique, all
the dependencies are automatically injected into this single instance in
proper order and returned to you. All objects of a similar lifetime are
grouped into this single factory.
Misko uses the example of building a "House."
Notice that in the House class, there are no instances of "new." Remember, don't mix new and logic,
baby. Like J-Lo and Puffy. All the dependencies needed to build a
"House" are injected into the constructor. All the "new" stuff is in the
HouseFactory (seen below).
In
the "house" factory, when build() is called, kitchen is created and
composed of sink, dishwasher, and refrigerator objects. Bedroom is
created and composed of created bed and dresser objects. House is
created, composed of kitchen and bedroom objects, then returned to the
user.
Using
this technique, you can see how easy it will be to achieve a single
configuration object without the use of a Singleton. A single instance
of HouseBuilder is instantiated in the main and with that comes single
instances of house, kitchen, bedroom, sink, dishwasher, refrigerator,
bed, and dresser.
Using
this technique solves the issue of global state because "there is no
global state at all. Every object only has references to what it needs
directly! No passing around of objects which are not directly needed by
the code. Dependencies are obvious since each object only asks for what
it needs."
Using
this technique solves the issue of memory management. All classes will
be created and used when needed. No more Singletons sitting around and
taking up memory while doing nothing at all.
Using this technique you can extend any of the classes you desire. Static methods are nowhere. No-sir.
Using this technique you can Unit-Test without fear of a wolf attack.
Plus, Misko adds:
If an object needs a reference to a new dependency it simply declares it. This change only affects the corresponding factory, and as a result, it is very isolated.All of the new operators end up in the factories; application logic is devoid of new operators.You group all of the objects with the same lifetime into a single factory (If the factory gets too big you can break it up into more classes, but you can still think of it as a single factory)
Look Lisa, I'm learnding
I loved Singletons.
Then I loved Singletons a bit too much.
Then I loved Singletons a bit too much.
Then I read Steve Yegge.
He broke my heart.
He broke my heart.
I sought answers.
If you are going to use Singletons I urge you to use Dependency Injection.
But really you should know that their are very few reasons to actually use a Singleton.
I think what you probably want is: a single instance of a class!
If this is true: try using an object plus a factory.
and Don't mix the "new" with the "logic" baby.
But really you should know that their are very few reasons to actually use a Singleton.
I think what you probably want is: a single instance of a class!
If this is true: try using an object plus a factory.
and Don't mix the "new" with the "logic" baby.