Singletons Are Evil Part 2

A while back I wrote a post about why singletons are evil. I still agree with that statement, yet after my comment on twitter today, I think I need to show how you can solve this problem differently.

The first problem we need to solve is creating the instance itself. This can become difficult if we have dependencies and we are trying to limit the creation. For example we have class Foo that is our singleton:

public static class Foo
{
	static Foo instance;
	
	public static Foo Current
	{
		if (instance == null)
		{
			instance = new Foo();
		}
		return instance;
	}
	
	public void SomeMethod()
	{}
	
	public void SomeOtherMethod(int x, int y)
	{}
}

Great! Easy enough and no big issues other than this is quite contrived and nothing in the real world is this easy. So lets go ahead and tackle the next big problem: Multithreading. We fix our class with a double check lock and end up with this:

public static class Foo
{
	static volatile Foo instance;
	static object syncObj = new object();
	
	public static Foo Current
	{
		if (instance == null)
		{
			lock (syncObj)
			{
				if (instance == null)
					instance = new Foo();
			}
		}
		return instance;
	}
	
	public void SomeMethod()
	{}
	
	public void SomeOtherMethod(int x, int y)
	{}
}

I am starting to feel a little dirty, but I can handle a little dirt. Now we are good except that Foo now has a dependency: Bar. Why the dependency? Well that is the object that we use to get some of the information we want in our singleton. Ok, lets see what this looks like:

public static class Foo
{
	readonly Bar bar;
	static volatile Foo instance;
	static object syncObj = new object();
	
	private Foo(Bar bar)
	{
		this.bar = bar;
	}
	
	public static Foo Current
	{
		if (instance == null)
		{
			lock (syncObj)
			{
				if (instance == null)
					instance = new Foo(new Bar(new Baz()));
			}
		}
		return instance;
	}
	
	public void SomeMethod()
	{}
	
	public void SomeOtherMethod(int x, int y)
	{}
}

At this point alarm bells should be going off and your brain should be going to DEFCON 1. We introduced Bar only to see that it needed a Baz. We have violated SRP and coupled all our classes together. Now imagine writing a test around any class that needed to use Foo. You get one Foo and all its dependencies that need to be cleared between tests. This causes you to write that clear method on your class that really is only needed to get rid of state you were trying to support anyway.

So hopefully by now, we agree that this is evil. Yet, I agree that singletons are something useful in the right scenario. So how can you avoid Global Thermonuclear War when using a singleton? Well fire up your trusty IoC container and let it manage it for you. Here is an example in Unity.

public class Baz{}
public class Bar
{
	readonly Baz baz;
	
	public Bar(Baz baz)
	{
		this.baz = baz;
	}
}

public class Foo
{
	readonly Bar Bar;

	public Foo(Bar bar, Baz baz)
        {
		Bar = bar;
		Baz = baz;
	}
	
	public void SomeMethod()
	{}
	
	public void SomeOtherMethod(int x, int y)
	{}
}
...
IUnityContainer container = new UnityContainer();
container.RegisterType(typeof(Baz), typeof(Baz));
container.RegisterType(typeof(Bar), typeof(Bar));
container.RegisterType(typeof(Foo), typeof(Foo), new ContainerControlledLifetimeManager());

Now we have separated the creation of the object and it’s life time from the object itself. This way we let the container handle the singletoness of the object and it’s creation. You still have to deal with multithreaded access to the dependencies of Foo, but when you decide that is just way to evil and there are better ways to solve this problem, you can change the lifetime management and go on about your business. This also frees you up to easily test this object and perform refactorings (like the ones Sean is talking about this month).

Did I mention singletons are evil?

Deliverance by Opeth


Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Scott Densmore

A transplant from Seattle to Florida trying to bring some community love to the sunshine state. And don't call me a hippie.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://thelimberlambda.com/ Eric Smith

    Shouldn’t line 19 of the third listing be:

    instance = new Foo(new Bar(new Baz()))

  • http://www.adverseconditionals.com Harry M

    You can use a static constructor on the class to initialise the instance: http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe

  • CNemo

    How does it prove that singleton is evil? :-0

  • http://claudiolassala.spaces.live.com Claudio Lassala

    Yeah, Deliverance by Opeth is awesome!! *That* is evil. :)

  • http://www.ecomval.gov.ph/comvalenyo/blogs/entry/asics-shoes-a-look-will-be-tenderness-of-each- Asics Gel

    great blog post, i surely adore this site, keep on it.

  • http://www.kerrrtivolsafdf.com/ kerrrtivolsafdf

    Thanks pal. This is nice knowing

  • http://www.register-web-domain.in Domain register

    Great content I keep learning new things every day from post like these. Good stuff!

  • http://www.bit-cart.com/ shopping cart software

    Well great addition to my knowledge, its good to keep learning all the time.

  • codematrix

    It’s not that singletons themselves are bad but the GOF design pattern is. The only really argument that is valid is that the GOF design pattern doesn’t lend itself in regards to testing, especially if tests are run in parallel.

    Using a single instance of an class is a valid construct as long as you apply the following means in code:

    1. Make sure the class that will be used as a singleton implements an interface. This allows stubs or mocks to be implemented using the same interface

    2. Make sure that the Singleton is thread-safe if necessary. That’s a given.

    3. The singleton should be simple in nature and not overly complicated.

    4. During the RUNTIME of you application, where singletons need to be passed to a given object, use a class factory that builds the depending object and have the class factory pass the global singleton instance to the depending object that requires it.

    5. During TESTING and to ensure deterministic behavior, create the singleton class as separate instance as either the actual class itself or a stub/mock that implements its behavior and pass it as is to the object that requires it. Don’t USE the class factor that creates that object under test that needs the signleton during test as it will pass the global singleton instance, which defeats the purpose.

    We’ve used Singletons in our solutions with a great deal of success that are not tightly bound, extensible, replaceable and are testable, ensuring deterministic behavior in parallel test run streams.

    codematrix