My musings about .NET and what not

Singletons vs. Static Classes

My last "versus" post seemed to elicit a good number of interesting responses. Today, I'm musing about Singletons vs. Static Classes -- two constructs which appear to accomplish the same task. Or do they?

The singleton pattern, as applied to a class, is a design pattern that is used to restrict instantiation of that class to a single instance. A singleton is responsible for creating and maintaining its unique instance, and must define a public member that grants clients a global point of access to the unique instance.

A quick Google search will fetch you a number of canonical examples of singletons. Listing 1 more or less follows the implementation presented by the GoF, modified for C#.

namespace Samples.Singleton
{
   public class Globals
   {
      private static Globals instance = new Globals();
 
      protected Globals()
      {
      }
 
      public static Globals Instance
      {
         get { return instance; }
      }
 
      public void DoSomething()
      {
         // do something here
      }
 
      public void DoSomethingElse()
      {
         // do something else here
      }
   }
}

Listing 1 

In Listing 1, the Singleton.Globals class contains logic to ensure that one and only one instance of the class can be returned via the Instance property. By making the constructor protected, we insure that the class cannot be instantiated in any other way except by accessing the Instance property.

(Now I understand that the above example is not thread safe, blahblahblah. Deal with it. It isn't really important to the discussion that follows.)

Listing 2 verifies that multiple references to the Instance property refer to the same instance in memory.

namespace Samples
{
   using System;
   using Globals = Singleton.Globals;
 
   public class Program
   {
      public static void Main(string[] args)
      {
         TestEquality();
      }
 
      private static void TestEquality()
      {
         Globals objA = Globals.Instance;
         Globals objB = Globals.Instance;
 
         if (ReferenceEquals(objA, objB))
         {
            Console.WriteLine("Instances are equal");
         }
         else
         {
            Console.WriteLine("Instances are not equal");
         }
 
         //// OUTPUT: Instances are equal
 
         Console.ReadLine();
      }
   }
}

Listing 2

I can certainly see where the Singleton pattern might be useful in modeling global resources like application logs, configuration settings, database connections, and so on. That being said, I have to admit that I haven’t made much use of the Singleton pattern in my projects. In the past, whenever I’ve thought “global object”, my next thought has pretty much always been “static class”, like in Listing 3.

namespace Samples.Static
{
   public static class Globals
   {
      public static void DoSomething()
      {
         // do something here
      }
 
      public static void DoSomethingElse()
      {
         // do something else here
      }
   }
}

Listing 3

Consuming the DoSomething method is pretty much the same either way, as shown in Listing 4.

private static void CallMethods()
{
   // call to static class method
   Static.Globals.DoSomething();
   
   // call to singleton class method
   Singleton.Globals.Instance.DoSomething();         
}

Listing 4

I don’t know about you, but to me, there doesn’t appear to be a whole lot of practical difference here, at least on the surface. The other day I started thinking about this a little more. I wanted to see if I could determine, in situations where I’d want to provide global access to a bunch of functions, if there was any real advantage to using the Singleton pattern rather than a static class.

Inheritance

What if you wanted to derive a new class from either of these? Since static classes are implicitly sealed, you’d have to remove the static modifier from the Static.Globals class -- in which case you no longer have a static class, just a regular class with a bunch of static methods. And besides, isn’t inheriting from a class with essentially no instance behavior kind of… well, pointless?

On the other hand, it looks like there could be some value in subclassing Singleton.Globals. Listing 5 shows a naive first attempt.

public class Globals2 : Globals
{
   public void DoMoreStuff()
   {
      // do more stuff here
   }
}

Listing 5

Let’s think about this for a minute. The functionality of a singleton relies on the fact that the only the class can create an instance of itself. That means that the derived class will inherit the same functionality, and thus will only be able to create an instance of Globals. In other words, a reference to Globals2.Instance will always yield an object of type Globals. As written, there’s no way to create an instance that actually lets us call the DoMoreStuff method.

So, how would we even create an instance of Globals2, in order to leverage its additional functionality? We’d certainly have to give Globals2 its own private field to hold the instance, and then give it its own Instance property to access that field. This Instance property would have to hide the inherited behavior of Instance from Globals, as in Listing 6.

public class Globals2 : Globals
{
   private static readonly Globals2 instance = new Globals2();
 
   public new static Globals2 Instance
   {
      get
      {
         return instance;
      }
   }
 
   public void DoMoreStuff()
   {
      // do more stuff here
   }
}

Listing 6

This works, but there’s hitch – it is now possible to create multiple separate instances of the Globals class – one from Globals.Instance, one from Globals2.Instance, and so on for each derived class. And therein lies the rub: if you can create multiple instances of a class, the class is no longer a singleton, right? It would seem that allowing inheritance on a singleton breaks the pattern definition of “one and only one instance.”

Upon further study, you’ll find another important limitation of this approach. As we’ve seen, it’s possible to derive classes from a base class that are intended to be singletons. However, the one thing you cannot do, under the inheritance scenario presented above, is to use the the base class to enforce the singleton behavior; that is, you can’t actually guarantee that any class derived from it will be a singleton. Consider Listing 7.

public class Globals3 : Globals
{
   // This is NOT a singleton
 
   public new static Globals3 Instance
   {
      get
      {
         return new Globals3();
      }
   }
 
   public void DoEvenMoreStuff()
   {
      // do even more stuff here
   }
}

Listing 7

Listing 7 shows a Globals3 class that inherits from the singleton Globals, but is itself not a singleton -- there is no restriction here on how many Globals3 instances you can create using this construct. Therefore, with simple inheritance, it’s up to the developer to hand-implement the full singleton pattern in each derived class.

The verdict would appear to be that, while you can subclass a singleton, there are a number of pitfalls to using this approach.

Factory Implementation

As we’ve seen, with inheritance, you need to track instances, and provide a point of access to the instance, in each individual derived class. Next, I wanted to see if there was a way to improve on this.

In Listing 8, I’ve opted to use a GetInstance method rather than an Instance property, so I could add some factory logic. (Again, I realize you’d have to add locks and such to make this thread-safe.)

namespace Samples.SingletonFactory
{
   using System;
   using System.Collections.Generic;
 
   public class Globals
   {
      private static Dictionary instances = new Dictionary();
 
      protected Globals()
      {
      }
 
      public static Globals GetInstance(Type type)
      {
         if (!instances.ContainsKey(type))
         {
            instances.Add(type, null);
         }
 
         if (instances[type] == null)
         {
            instances[type] = (Globals) Activator.CreateInstance(type, true);
         }
 
         return instances[type];
      }
 
      public void DoSomething()
      {
         // do something here
      }
 
      public void DoSomethingElse()
      {
         // do something else here
      }
   }
 
   public class Globals2 : Globals
   {
      private Globals2()
      {
      }
 
      public void DoMoreStuff()
      {
         // do more stuff here
      }
   }
 
   public class Globals3 : Globals
   {
      private Globals3()
      {
      }
 
      public void DoEvenMoreStuff()
      {
         // do even more stuff here
      }
   }
}

Listing 8

Here, in the Globals singleton base class, I’m using a generic Dictionary to track instances of any classes derived from it. The logic in the GetInstance method assures that no more than one instance of any particular subclass can be instantiated.

This certainly does make it easier to provide singleton behavior to derived classes, as the subclasses don’t have to implement their own singleton pattern or store their own instances. (Of course, it’s still possible to break the singleton pattern as before, but at least now you’d kinda have to go out of your way to do it.)

I guess I can see where this Singleton/Factory pattern could be handy for situations where you’d want to pull the derived type you want to instantiate out of a configuration file, for example. But I’m also seeing how much additional complexity is being introduced here. Listing 9 makes my YAGNI bell go off big time!

private static void CallMethods2()
{
   // call to static class method
   Static.Globals.DoSomething();
 
   // call to singleton factory method
   SingletonFactory.Globals.GetInstance(typeof(SingletonFactory.Globals)).DoSomething();
}

Listing 9

Hmmm… so much for that “simplest thing that could work” rule.

And once again I would point out that, because this allows you to create multiple instances of the Globals class (one for each derived type), we still seem to be stretching the concept of “singleton” well beyond its original meaning.

Conclusion

At first glance, it would appear that there are at least two distinct advantages of a singleton over a static class: 1) the ability to create (meaningful) derived classes, and 2) the ability to add factory-like behavior. But after a little further investigation, I’m still doubting the suitability of the Singleton pattern for most situations where access to a simple global object is required.

First, I still haven’t reconciled myself to the fact that, in order to extend the functionality of a singleton beyond that of a regular static class, you really need to allow more than one instance, which appears to violate the spirit of the whole singleton concept.

Second, I’m not comfortable that it doesn’t appear to be possible to guarantee that a class derived from a singleton will always be a singleton (maybe there’s a way to do that I just haven’t figured out yet?)

Third, singletons appear to me to add a layer of complexity that just isn’t required unless you’re attempting to pull off something really fancy.

Maybe someone will come along, blow me away with a cool implementation I haven’t considered, and make me a singleton fan-for-life. Until then, I’ll probably be sticking with those good ol’ fashioned static classes.

Subscribe to this blog for more cool content like this!

kick it on DotNetKicks.com

shout it on DotNetShoutOut.com

vote it on WebDevVote.com

Bookmark / Share

    » Similar Posts

    1. Should We Return Null From Our Methods?
    2. Interfaces vs. Abstract Base Classes
    3. If At First You Don’t Succeed - Retrying Mail Operations in .NET

    » Trackbacks & Pingbacks

    1. You've been kicked (a good thing) - Trackback from DotNetKicks.com

      Singletons vs. Static Classes — April 27, 2009 2:44 PM
    2. Thank you for submitting this cool story - Trackback from DotNetShoutout

      Singletons vs. Static Classes — April 28, 2009 3:56 PM
    3. Over the weekend in between run throughs that I did prepping for a webcast, I did some catch-up blog

      Interesting reads — April 28, 2009 10:38 PM
    4. Pingback from Reflective Perspective - Chris Alcock » The Monring Brew #337

      Reflective Perspective - Chris Alcock » The Monring Brew #337 — April 29, 2009 2:36 AM
    5. 9efish.感谢你的文章 - Trackback from 9eFish

      Singletons vs Static Classes : LeeDumond.com — April 29, 2009 8:40 PM
    6. Pingback from Friday Links #49 | Blue Onion Software *

      Friday Links #49 | Blue Onion Software * — May 1, 2009 8:49 PM
    7. Pingback from Weekly Links #51 | GrantPalin.com

      Weekly Links #51 | GrantPalin.com — May 3, 2009 8:28 PM
    8. Pingback from Interesting reads | Coded Style

      Interesting reads | Coded Style — May 6, 2009 11:26 PM
    9. Pingback from Interesting reads | Coded Style

      Interesting reads | Coded Style — May 6, 2009 11:32 PM
    10. .NET Introduction to MapReduce for .NET Developers Working With the ANTS Profiler to Optimize SharePoint

      Interesting Finds: 2009 05.01 ~ 05.10 — May 9, 2009 10:17 PM
    11. If you are looking to follow this series, be sure to subscribe to my RSS feed at http://feeds.jasongaylord

      Technology Related Links for May 11th — May 11, 2009 4:14 PM
    Trackback link for this post:
    http://leedumond.com/trackback.ashx?id=52

    » Comments

    1. Billy avatar

      add the complexity to do unit testing when one of the collaborators is a singleton; singletons are really difficult to mock.

      Billy — April 28, 2009 4:53 PM
    2. Lee Dumond avatar

      @Billy - I hadn't even thought of that. Great point.

      Lee Dumond — April 28, 2009 4:59 PM
    3. Alex James avatar

      Good read, this is definitely one of the least well understood areas of .NET development for some... thanks.

      Alex James — April 28, 2009 10:51 PM
    4. Rob Scott avatar

      Using the Monostate pattern instead of a singleton can make mocking much easier.

      Rob Scott — April 29, 2009 10:48 AM
    5. Timm avatar

      Here's a twist on your discussion: static classes that access singletons. In other words, provide a static class which developers access, and then that static class automatically creates and calls methods in the singleton. This provides the benefits of a static (single class that can be accessed globally) with the benefits of a singleton (derived classes and factory-like behavior). It's a little extra work for the developer, but the benefits are worth the effort in many cases.

      Timm — April 29, 2009 1:40 PM
    6. Gonzalo Bianchi avatar

      I never fully understand what this pattern should be doing. Isn't this just a prettier way of having a global public class instanciated at the beggining of your program?

      Maybe it's just me, because I saw to many languages, but I really see no point in doing this. There is no safety in doing this, if the only instance is modified by another programer in another part of my system, where is the difference in safety with just having a global class?

      Gonzalo Bianchi — April 29, 2009 1:44 PM
    7. Lee Dumond avatar

      @Gonzalo - It's my understanding that the Singleton pattern was developed (at least in part) as an alternative to application-level global variables. Global variables that are instantiated when an app starts always consume resources, whereas the Singleton supports lazy allocation where an instance is created only as needed.

      Having said that, I agree with you -- this was in fact pretty much the whole point of my post. Oftentimes, a singleton appears to me to be a solution in search of a problem. In many applications in which I've seen them used, I'd probably have opted to use a global static class instead. Simpler, quicker, and more YAGNI-compliant.

      Lee Dumond — April 29, 2009 2:08 PM
    8. Thomas Johnson avatar

      I've used the Singleton pattern to provide a shared database connection to improve performance in a .net CE app. How would you do that using a static class?

      I think the main difference between a Singleton and Static classes is that you can hold data in a singleton.

      Thomas Johnson — April 30, 2009 10:22 PM
    9. dave avatar

      @thomas johnson:

      You can have static properties and static fields as much as you like in static classes too, and use static constructors to fill them. You'll want to use locks though if you're storing data in them and accessing it from multiple threads, of course, but you'll have to do that no matter what unless you only use atomic operations.

      static class Foobar {

      static string myString = string.Empty;

      public static string GloballyAccessibleString {

      get {

      return myString;

      }

      set {

      myString = value;

      }

      }

      }

      Like that.

      dave — May 1, 2009 9:31 AM
    10. Al Tenhundfeld avatar

      @Billy So you think mocking a singleton is harder than mocking a static class? I disagree. Mocking a static class is extremely difficult/tedious (without a magic framework like TypeMock); mocking a singleton is fairly easy if you're using a factory/provider pattern.

      With a static class, you're really writing procedural code. You don't get any of the benefits of OOP. Besides, singleton is not a complicated or heavy pattern, especially if you're using an IoC/DI container.

      In my opinion...

      Al Tenhundfeld — May 1, 2009 9:34 AM
    11. Lee Dumond avatar

      @Al:

      >> You don't get any of the benefits of OOP.

      As I pointed out here, singletons do offer that advantage -- as long as you are willing to accept the fact that once you start deriving classes, you're no longer working with a singleton.

      Interestingly enough, I happened to notice today a singleton implementation on MSDN that was restricted with a *sealed* modifier. The reason given was as follows:

      "The class is marked sealed to prevent derivation, which could add instances."

      To me, this is acknowledgment of one of the points I've raised here -- singletons which leverage the "benefits of OOP" aren't really singletons at all.

      Maybe we should call them something else. Doubletons? Tripletons? Polytons, anyone? ;-)

      Lee Dumond — May 1, 2009 9:52 AM
    12. Al Tenhundfeld avatar

      I'm guessing our disagreement is based on our definitions of singleton. I view singleton as a pattern that defines the consumption of a type. You (I think) view singleton as a pattern that defines a type.

      "The class is marked sealed to prevent derivation, which could add instances."

      That idea is a bit strange to me. (A little googling shows that I'm probably crazy, and you're probably right.) But I don't see why the singleton implementation needs to be internal to the type. I don't really care if a type *is a singleton*, as long as all other code interacts with that type *as a singleton*.

      I sometimes like to expose an interface as a singleton; if I understand you correctly, that idea doesn't make a lot of sense in your view.

      Also, I feel pretty sure that you can still have a singleton with derived classes. To use an example somebody else mentioned above, let's say I have a data access coordinator singleton in a reusable library, exposed as a DataAccessCoordinator abstract base class. Different systems use that data access singleton with different derived classes. Maybe one system wants to log all DB queries; so they create a derived LoggedDataAccessCoordinator and make the singleton return an instance of it. Maybe another system wants an audit trail implemented in their DACoordinator. Maybe I want to create a MockDACoordinator that doesn't actually interact with a DB and instead just records the calls I make.

      My point is that in each system, only one instance of DataAccessCoordinator ever exists at runtime, but it could be a derived type.

      Does this make sense, or am I just crazy?

      Al Tenhundfeld — May 1, 2009 10:26 AM
    13. Al Tenhundfeld avatar

      BTW, for the record, I actually try to avoid using singletons. But if my options are singletons or static classes, I will choose singleton in most cases.

      In my experience, static classes often end up being gigantic catch-all classes that are never refactored. I'm sure they can be used effectively; I just rarely see it.

      Al Tenhundfeld — May 1, 2009 10:33 AM
    14. Caleb avatar

      Normally what I do when I have something where I only really want to work with one instance and I want it to be extensible is create an interface exposing the functionality I need. Then I create a static class that provides a static reference to the implementation of that interface. That way I can just change the implementation that is being used based on some configuration or some other need (this could be some sort of IoC container). The actual implementations don't normally prevent you from creating multiple instances, but the program would not normally instantiate an instance because it uses the static class to find the instance.

      I tend to find normally that preventing someone from instantiating two instances isn't worth it. As you generally don’t even know which implementation you will be using when you’re writing the code that accesses it.

      Caleb — May 1, 2009 10:50 AM
    15. Randolph Cabral avatar

      I try to avoid the singleton pattern and static classes as much as possible in favor of DI/IoC containers. With static classes and singletons, you can run into issues with thread safety. With current hardware trends doubling processors every few years, it would be best to stay away from static classes unless you are writing extension methods. Most DI frameworks allow you to register objects with the IoC container in a scoped fashion (i.e. singleton, httpsession, etc).

      Randolph Cabral — May 1, 2009 12:06 PM
    16. Avram Korets avatar

      The Clean Code Talks - "Global State and Singletons" www.youtube.com/.../watch

      To me, DI is too complicated, but anyway Misko Hevery right, and Singleton is bad design practice.

      Avram Korets — May 1, 2009 12:51 PM
    17. S.T. avatar

      I recently posted a message on the MSDN forums about this issue -- static classes vs singletons. Actually, I really didn't know much about singletons until I posted that message. My issue was that I was using a static class (for 'global' use) and it wasn't being properly destructed. Meaning, I would implement a destructor but it would never get called.

      I then realized that static classes don't get destructed until, I think, after the program exists. So if I was using, for example, COM object code that had to be explicitly garbage-collected, I would need to either implement a Singleton class (which I did), or I had to explicitly create and call a 'Close()' method in my static class that would do all the garbage collection.

      So long story short, there is that one other difference between a static class vs singleton -- the ability to have a destructor in a singleton (as it is instantiated normally like a regular non-static class).

      S.T. — May 1, 2009 1:56 PM
    18. Ray Henry avatar

      My strategy is to avoid Static classes at all costs and use a DI container to supply Singletons when necessary.

      I should qualify that to say that I avoid Static classes in components that I develop. It's important to realize the difference between the components you develop that make up your application and the container application that pulls everything together. Avoid the statics in components in order to limit dependencies. Once you reference something in a component, you are going to need to pull it into any other app you create to re-use the component. Avoid the static and use an interface-based singleton.

      Statics are ok in your wrapper app that pulls all the components together and configures everything.

      Ray Henry — May 2, 2009 9:05 AM
    19. Sohan avatar

      There are situations, where you actually need singleton classes and cannot use a static class. Here is an example.

      An application needs one and only one logger. However, based on configuration it may use Log4Net or EventLog. But, I can only use one instance of the two types across the whole application.

      If you use static, you will not be able to switch between the two types unless changing your code. But using singleton and a factory, you can do this.

      Sohan — May 3, 2009 10:36 PM
    20. AJ.NET avatar

      I think - and no offense intended - that there is some misconception in the following sentense: "The singleton pattern, as applied to a class, is a design pattern that is used to restrict instantiation of that class to a single instance."

      Note: For the time being let's assume we are talking about accessing some shared data or ressouce, otherwise this discussion is a little pointless.

      First, a singelton is not about or applied to a _class_. It's about some _instance_ (more like shared state from the point of view of the consumer), not tying that instance to a certain type. Actually this way inheritance and interfaces become meaningfull, e.g. using a factory:

      public static IMySingelton Instance

      {

      get

      {

      if(instance==null)

      instance= Factory.Create();

      return instance;

      }

      }

      This is a very valid design that provides extension points (in case of framework or library implementations), and is easy to mock.

      Secondly you are overlooking the scope/context that is tied directly to the pattern. There is no such thing as a singelton per se, there is only a singleton _in a given scope_.

      Static data automatically has "AppDomain" as scope (context as well as life time). But there are other scopes as well: thread, web request, page, machine, user, etc..

      Granted, AppDomain is the scope employed mostly, yet even if that suits you, expecting a singleton to be the one and only instance is futile in applications that have multiple AppDomains (web apps for example, e.g. during app domain recycling and in web garden scenarios). Log4net's file appender keeps the trace file open and falls into exactly that pitfall, essentially because the singleton didn't have the same scope as the ressource it depends on.

      Anyway, in most cases where I start with a static class I end up with a singelton implementation. Reasons vary but here are some examples:

      - Controlled/lazy initialization. Create the instance explicitely or only when it is needed (which is sometimes necessary because construction may depend on other information).

      - Destruction. Deterministically free the resources aquired by the instance.

      - Type. Define the contract by an interface or base class and create the singleton via a factory.

      - Testing. Unit testing the singleton class (e.g. recreate a clean instance for each test) as well as replacing it by a mock object.

      - class design. A class that maintains its own data members suits me far better than a bunch of static methods maintaining a bunch of static data. (Strictly my own sense of aesthetics of course.)

      - Scope. Static classes are limited to "1 instance per app domain". Singletons can have different scopes, e.g. instance per thread, per request, per whatever.

      - Code artefacts. Singeltons allow for events and properties.

      Regards,

      AJ.NET — May 4, 2009 6:33 AM
    21. foobar avatar

      Scope? You mean like per server?

      This obsession with singletons is tiresome. Usually it just tells me who hasn't worked on projects with multi-server instance requirements.

      foobar — May 13, 2009 5:19 PM
    22. Eric avatar

      Very simply, you can't pass a static class.

      A singleton can implement an interface and can be passed to methods that expect that interface. A static class cannot.

      Eric — May 14, 2009 10:33 AM
    23. Jinx avatar

      How about this...What can we have...? a static UserControl or/and single instance Usercontrol...?

      Jinx — September 16, 2009 2:52 PM
    24. learner avatar

      Lots of brainstorming. great read . Thanks.

      learner — November 27, 2009 12:30 PM
    25. Visual C# Kicks avatar

      I find the concept of singleton classes very cool (especially when you add multi-threading into the mix).

      But I agree I haven't found many cases where a singleton class was clearly the way to go. Might just be a preference thing.

      Visual C# Kicks — February 25, 2010 2:50 PM
    26. ezmoz avatar

      Good quality of post. Rock'n roll.

      ezmoz — August 15, 2010 2:25 AM
    27. dboarman avatar

      I am considering the design of 3 static classes specifically for 3 different database drivers: MySql, OleDb, and ODBC. The static classes are providing driver specific functions. In the design concept is a singleton that is shared by all 3 static data providers. The singleton (implements IDIsposable) would make use of IDataReader, DbConnection, etc. Would this be considered a decent design concept? What are pitfalls in this design that I should consider? What makes this design concept good or bad?

      dboarman — August 17, 2010 9:25 AM
    28. Can You tell me why code in Listing 1 isn't thread safe?

      3P — January 21, 2011 1:52 PM

    » Leave a Comment