Sunday, August 31, 2014

Singleton I love you, but you're bringing me down (repost)

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.
Then I read article after article about why the Singleton was a piss poor Design Pattern.
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:
public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}
rather than this:
public MyConstructor() {
    this.singleton = Singleton.getInstance();
}
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."
class House {
  private final Kitchen kitchen;
  private final Bedroom bedroom;
  private boolean isLocked;
 
   public House(Kitchen kitchen, Bedroom bedroom) {
    this.kitchen = kitchen;
    this.bedroom = bedroom;
  }
 
  private boolean isLocked() {
    return isLocked;
  }
 
  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}
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).
class HouseFactory {
  House build() {
 
     Sink sink = new Sink;
     Dishwasher dishwasher = new Dishwasher;
     Refrigerator refrigerator = new Refrigerator;
     Kitchen kitchen = new Kitchen(sink, dishwasher, refrigerator);
 
 Bed bed = new Bed;
     Dresser dresser = new Dresser;
     Bedroom bedroom = new Bedroom(bed, dresser);
 
 House house = new House(kitchen, bedroom);
 
    return house;
 
  }
}
 
class Main {
  public static void(String...args) {
    House house = new HouseFactory().build();
    house.lock();
  }
}
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 read Steve Yegge.
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.