The Singleton Pattern – Design patterns in practice II.

The Singleton pattern is one of the most well-known and probably the most often used design pattern. It is used to enforce that only a single instance of a class can be instantiated within an application (To be more precise within an AppDomain. For more details please see remarks at the bottom). The key of this pattern’s success is its well focused object and easy implementation.

Despite all the merits there are a lot of misunderstanding around the proper implementation and usage of the Singleton pattern.

First of all it is a code smell to use the singleton pattern extensively since it introduces a kind of global memory. When used for instrumentation it is fine. However my experience shows that in a lot of cases too much business logic is put into this structure needlessly going against design principles. Here a nice description can be found over the deficiencies of the Singleton pattern.

The simplest implementation of the singleton pattern is shown in Example 1. The instance of the class is stored within a static field and is instantiated in the field initializer. If the construction of the instance is more complex then a static constructor can be used. Usually this solution works perfectly and easy to implement and understand.

Example 1:


public class Singleton
{
   private static Singleton _instance = new Singleton();
   
   public static Singleton Instance
   {
      get { return _instance; }
   }
   
   private Singleton()
   {
      Console.WriteLine("Singleton created");
   }
}

The reason many refuse this simple implementation is the lack of lazy initialization. The basic idea is to instantiate the singleton class only on demand to save memory and gain more control over the life-cycle of the singleton. But if an application always instantiates the Singleton then there is little use of lazy initialization in terms of memory usage. Often there is neither real need for the life-cycle control.

When lazy initialization is beneficial double checked locking can server as a simple but efficient solution. The first check is to avoid any locking if the singleton is already created. The following lock statement ensures that only single thread can enter the critical section of object creation at a time. Since multiple concurrent threads can be blocked by this lock a second check is needed within the critical section to avoid the recreation of the singleton. Note that to support multi-thread environment the volatile keyword must be used. The implementation of double checked locking is shown in Example 2.

Example 2:


public class Singleton
{
   private static object _instanceLock = new Object();
   private static volatile Singleton _instance;
   
   public static Singleton Instance
   {
      get
      {
         if (_instance == null)
         {
            lock(_instanceLock)
            {
               if (_instance == null)
               {
                  _instance = new Singleton();
               }
            }
         }
         return _instance;
      }
   }
   
   private Singleton() { Console.WriteLine("Singleton created"); }
}

There is a more elegant solution that omits any explicit locking. The C# 4.0 language specification (10.12) says

The static constructor for a closed class type executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class type is created.
  • Any of the static members of the class type are referenced.

Buildt upon the fact that the body of the static constructor executes at most once locking becomes avoidable. In Example 3 a private inner class is introduced with a single static field that holds the singleton instance and a static constructor that initializes it. According to the specification the instance is instantiated when the Instance property accessor of the Singleton class gets called. And this is exactly how lazy initialization must work.

Example 3:


public class Singleton
{
   public static Singleton Instance
   {
      get { return _InstanceContainer.Item; }
   }
   
   private class _InstanceContainer
   {
      public static readonly Singleton Item;
      static _InstanceContainer()
      {
         Item = new Singleton();
      }
   }
   
   private Singleton()
   {
      Console.WriteLine("Singleton created");
   }
}

As mentioned in the introduction the scope of static items is AppDomain. But this can be overriden. If a field is decorated with the attribute ThreadStatic then the scope narrows to thread level. That is, every single thread in the AppDomain will have its own instance of the static field.

The Visitor Pattern – Design patterns in practice I.

It is a common problem that a feature involves of processing elements of a class hierarchy based on their exact type. Using virtual functions is a plausible solution but can be cumbersome if too many features are implemented that way. To decouple the hierarchy of entities and the processing algorithm Visitor pattern is the way to go.

Example 1: There are several types of customers stored in the system. Depending on the type of customer you want to send an Xmas greeting. Enterprise customers are contacted by email, SMS goes to private customers and a memo is added to an external CMS system for every long-term customer. The feature must be designed without significantly changing the existing class structure and keep it as flexible as possible (later Eastern greetings might be needed).

Example 2: In a banking application different sort of account types are handled. At the end of the month a report must be generated per account including account type dependent information. The format of these reports can vary. The reporting process should be easily configurable and open for future changes.

Solution: The visitor pattern applies a different approach. The feature is implemented in a Visitor class that is dynamically called from entities.  As a consequence the feature and the class structure of entities are well separated.

Visitor Pattern UML

UML draft of the Visitor Pattern

Alternative solution 1: An obvious way is to use virtual methods. A base entity class declares an abstract virtual method and every derived class implements it. Then every client call is resolved to the proper instance. This solution is pretty straightforward; however, it affects the class structure even if the implemented feature is not strongly related to it. It can be also cumbersome to make the feature configurable.

Alternative solution 2: Another possibility is to use a static utility method that takes an entity as its parameter. The body of the method is based on a large switch – case statement over the type of the entity. This is a simple and effective solution if the class hierarchy of entities are simple and re-usability is not an issue.

Sample: Below you can find a sample code that corresponds to Example 1.

namespace VisitorPattern
{
    class Client
    {
        static void Main(string[] args)
        {
            Customer[] customers = new Customer[]{};
            XmasCardVisitor xmasCardVisitor = new XmasCardVisitor();
            foreach (Customer c in customers)
            {
                c.Accept(xmasCardVisitor);
            }
        }
    }

    public interface IVisitor
    {
        void Visit(EnterpriseCustomer c);
        void Visit(PrivateCustomer c);
        void Visit(LongTermCustomer c);
    }

    public class XmasCardVisitor : IVisitor
    {
        public void Visit(EnterpriseCustomer c)
        {
            //TODO
        }

        public void Visit(PrivateCustomer c)
        {
            //TODO
        }

        public void Visit(LongTermCustomer c)
        {
            //TODO
        }
    }

    public abstract class Customer
    {
        public abstract void Accept(IVisitor visitor);
    }

    public class EnterpriseCustomer : Customer
    {
        public override void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class PrivateCustomer : Customer
    {
        public override void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class LongTermCustomer : Customer
    {
        public override void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }
    }

}