Has the Singleton Not Suffered Enough

Has the Singleton Not Suffered Enough

By Omar Bashir

Overload, 21(117):15-21, October 2013


Singletons are much maligned. Omar Bashir considers why.

Singleton is an object creational design pattern that ensures only a single instance of a class can ever exist in an application and it provides a global point of access to that instance [ GoF94 ]. The classical Singleton structure is the simplest among design patterns. It involves a single class with a private or protected constructor and a class method which returns the same instance of that class whenever it is invoked. Its simplicity leads to a temptation to use it instead of global objects and in situations that require single instances of implementing classes. For these reasons, it is a very widely used pattern.

Hahsler’s quantitative study on adoption of design pattern also indicates that nearly 50% of Singleton implementations analysed were removed in subsequent maintenance [ Hahsler04 ]. While Hahsler suggests overuse of the pattern due to its simplicity, these removals may also be due to the evolution in applications and their requirements as well as the context in which they are used resulting in the need for more than one instance of the previously Singleton classes. This may also be due to inadequacies of the classical structure of this pattern which focuses only on the creation of the Singleton instance but ignores most other aspects such as concurrency, substitutability, extensibility, lifetime management etc. and introduces coupling.

It is interesting to consider Ignatchenko’s example of a flight simulator for a single one-engined aircraft that is constructed using singletons for the engine and the aircraft [ Ignatchenko12 ]. After its resounding success, the company is asked to deliver a simulator for a twin engined aircraft. The developers have to go through a significant refactoring exercise to remove singletons from their code. It is important to note the underlying implications of the initial decision to use singletons and then the potential consequences of their removal.

A major implication of using Singleton is instance control. Once the instantiation of a class is controlled within a context, global accessibility of that instance within that context is natural. The classical description of the Singleton pattern intends the context to be the executing program. Therefore, singletons are globally accessible within applications that use them.

If a limited number of instances of a class are required within a context, the ability to construct objects without any restriction adds vulnerability to the application. Developers may mistakenly or unknowingly instantiate additional objects, which may result in inconsistent operation of the program at best. Therefore, instance control needs to be enforced for such classes. Singleton is a form of this enforcement. Furthermore, instance control may be considered separately from accessibility even within a context. If accessibility of singletons is restricted, they need to be passed to their dependants via interfaces which makes associations more obvious.

This discussion argues that the intent of the Singleton to limit instances of a class is the actual pattern and not the prescribed structure. Many of the criticisms of Singleton ’s classical structure may be addressed with alternatives, some of which are discussed here. Furthermore, the structure can be adapted to suit the requirements of the problem, the technology being used and the desired qualities of the system being implemented. Finally, dependency instantiation in the context of the dependants will be discussed. In this text, Singleton refers to the design pattern and singleton refers to only one instance of a class of which multiple instances cannot be created.

Criticisms

Singleton is largely considered similar to a global variable as it penetrates a scope via mechanisms less obvious than the public interface of the dependant. Therefore, it adds coupling to its dependants which reduces their flexibility and extensibility [ Radford03 ]. This coupling is further exacerbated because a classical singleton usually requires the dependant to depend on a concrete class rather than an abstract interface. Therefore, it may be difficult to provide a mock or a stub of a singleton for unit testing its dependants.

The Singleton pattern only focuses on object creation and not its lifetime management. Even when a singleton is needed for the entire lifetime of the dependant application, issues may arise in the order in which a singleton is destroyed at program termination. This is because applications may run into issues if a singleton is destroyed while its dependants still hold a reference to it. This, therefore, requires mechanisms to manage the lifetime of singletons based on the context in which they are being used [ Alexandrescu01 ], [ Levine00 ]. However, this may not be a concern in managed environments where objects are only garbage collected when their references are no longer held.

Critics argue that the decision to create dependencies, the number of their instances and their lifetime management should rest with the domain and not the class itself [ Radford03 ]. They prefer PfA ( Parameterise from Above ) where the application instantiates the required objects and passes them as dependencies via a public interface. This provides greater opportunities to decouple dependencies and dependants via abstract interfaces [ Radford03 ], [ Love06 ]. However, there are arguments that PfA violates information hiding as the application may require explicit knowledge of coupling between the dependencies and dependants [ Radford03 ]. Furthermore, instantiating objects at the top level and passing them through several layers to the layer where these objects are required clutters the application layer with objects not required there and may also result in elaborate interfaces between layers to pass these as parameters.

Dependencies may be encapsulated into an object to simplify the interfaces of the dependants as described in the Encapsulate Context pattern [ Kelly04 ]. It may be argued that Encapsulate Context achieves this through obscurity by collecting (at times unrelated) parameters into a single object. Balancing openness (by using finer grained context objects) with interface cluttering and coupling can be challenging. As discussed later, instantiation of all dependencies at the application level may neither be appropriate nor feasible hence making Encapsulate Context and its variants inappropriate solutions for such relationships.

Singleton initialisation is also not obvious in the pattern. If a singleton is initialised at construction then initialisation parameters may need to be passed via the global access point. This means that dependants should have explicit information regarding the initialisation of their singleton dependencies. This may be alleviated via environment variables but at the cost of further obscurity. Also, the behaviour to be expected if a dependant passes different configuration parameters than the one passed earlier is unclear. Should the new configuration parameters be ignored? Should the existing instance be deleted and a new instance created? Or should the existing instance be re-initialised? One option is to separate initialisation from construction and make initialisation an instance operation. Once a dependant obtains the dependency, it should be able to determine if the dependency is already initialised. If not, the dependant should be able to initialise it. If the initialisation parameters change, it may be possible to reinitialise the dependency. However, issues may arise if the dependency is shared between a number of dependants.

Singleton creation and initialisation become more challenging in multi-threaded environments. Synchronising the global access point for a singleton instance is the safest but the least optimal option. Furthermore, construction or initialisation may be time consuming operations that may have performance implications for the entire application. For construction, optimisation is suggested using DCLP ( Double Checked Locking Pattern ) [ Schmidt97 ]. However, it has its limitations too when porting to multiprocessing architectures and using optimising compilers [ Meyers04 ]. Their remedies can, in turn, add considerable complexity to the creation and initialisation of a singleton.

Pattern is in the intent

The intent of Singleton is to provide a mechanism that allows only a single instance of a class and global access to that instance. Prescribing further than that starts making the pattern more implementation and technology specific. In fact, a strict prescription of any pattern structure has been criticised as practitioners tend to consider the structure as the pattern and not the intent and the context in which the pattern is to be applied [ Petersen13 ]. Hence, even with slight changes in the implementation, application or the context, the classical Singleton structure may result in issues discussed above. Furthermore, some recent languages provide Singleton as a language feature making the Singleton structure somewhat redundant for these languages. A typical example is the object construct in Scala. It is, therefore, unfortunate that the pattern receives significant criticism where many critics are actually criticising the prescribed structure and its weaknesses.

The key characteristic of the pattern is instance restriction, i.e., limiting the number of instances of a class to only one within an application. Thus, the mechanism providing a singleton should only ever return the same instance whenever an instance is requested. This makes global access to this instance inherent to the pattern. This is the strongest distinction between a global and a singleton. Normally global instances have public constructors allowing any number of global and local instances of their classes to be created [ GoF94 ]. Singleton aims to restrict public accessibility of the constructor so that it may only be called in a controlled manner allowing the developer to control the number of instances that can be created.

There have been arguments that dependency injection (DI) containers have the ability to provide singletons. However, DI mechanisms largely depend on public constructors of classes for which they provide instances. As discussed above, public constructors on a class allow a programmer to create an instance without using or bypassing DI thereby having multiple instances of the same class. So, these DI containers may claim to provide singletons only if these containers are used for instance creation and management. Some DI containers like Spring may provide support for the classical Singleton structure by allowing invocation of static methods on classes that return an instance of the respective classes. Furthermore, it can be argued that DI can also allow penetration of a scope in ways other than public interfaces, just as Singleton does.

Gang of Four (GoF) discuss variation of Singleton also referred to as Multiton or Limiton [ Stencel08 ], which provides multiple controlled instances of a class. They also discuss subclassing in Singleton which can be useful for substitutability, lack of which in the classical structure hinders flexibility and testability of systems using singletons. However, their detailed description on providing these features focuses on adapting the classical structure which adds significant complexity to just one class and requires additional support for creating an instance from a type hierarchy.

Therefore, most technical issues related to Singleton can be attributed to the structure prescribed by GoF rather than the pattern itself. While the classical structure satisfies the intent of the pattern, it violates key object oriented design principles like separation of concerns and substitutability, leading to higher coupling, low cohesion and significant rigidity in its implementation and use.

Separation of concerns

The classical Singleton structure exhibits low cohesion as it requires a single class to perform instance creation, instance management and provide the required functionality. This inhibits the extension or variation of these orthogonal aspects of the Singleton structure. Separating these non-overlapping and unrelated aspects into different classes allows independence between instance control and functionality of the singleton which enables each to be varied independently and increases cohesion in the respective classes.

SingletonHolder is a well documented Singleton implementation in C++ that focuses on the intent of the pattern and uses separate classes to perform singleton object creation, instance management and thread safety [ Alexandrescu01 ]. SingletonHolder itself is not a singleton and does not contain any application or domain functionality. All construction methods of the application specific class whose instance is to be managed by SingletonHolder are private to avoid unintended construction. This requires a friendship to be declared between the application specific class and the class implementing the creation policy. SingletonHolder is an example of policy-based design. Type parameterisation allows customisation of instance creation, thread safety and singleton lifetime management independently of the functionality of the singleton object a SingletonHolder manages.

Absence of the friend relationship in Java and the difference between Java Generics and C++ templates will not allow a similar implementation in Java. Classes whose constructors have restricted access may not be instantiated except through reflection. Furthermore, it is not possible to declare a static variable of generic type in Java to hold the reference to the singleton instance. A minimal Java-based SingletonFactory that only instantiates a singleton and holds its reference is shown in Listing 1.

public class SingletonFactory {
  private static
     Map<Class<?>,Object> instanceMap;
  static{
    instanceMap = new HashMap<Class<?>,Object>();
  }

  public <T> T getInstance(Class<T> type)
                throws InvocationTargetException,
                       IllegalAccessException,
                       InstantiationException,
                       NoSuchMethodException{
    if (!instanceMap.containsKey(type)){
      Constructor<T> constructor =
         type.getDeclaredConstructor();
      constructor.setAccessible(true);
      instanceMap.put(type,
                      constructor.newInstance());
    }
    return (T) instanceMap.get(type);
  }
}
			
Listing 1

The instance created by an instance of SingletonFactory is inserted into a map ( instanceMap ) with the key being the class of the instance created. A SingletonFactory instance creates an instance of a specified class only if no other instance of that class exists in the instanceMap . The getInstance() method always returns a class’s instance from the instanceMap . The following snippet shows the usage of SingletonFactory where the constructor of Singleton1 class is private.

  ...
  SingletonFactory factory =
     new SingletonFactory();
  Singleton1 o1 =
     factory.getInstance(Singleton1.class);
  ...

While using reflection to access private members of a class may raise eyebrows, the SingletonFactory implementation removes the instantiation logic from the application/domain class allowing SingletonFactory to be implemented only once and adapted independently of the domain/application logic contained in the singleton classes.

Extensibility and substitutability

GoF suggest extensibility in the classical Singleton through subclassing, which also allows substitutability. They mention selection of an instance of a specific subclass as a key challenge in a Singleton type hierarchy. Some of the solutions they suggest include using a registry of instances of Singleton classes in a hierarchy, statically linking a specific Singleton subclass and using a single method in the base class for the entire hierarchy to determine the actual subclass and return its instance. Some dependency injection containers like Spring support classical Singleton by allowing invocation of a static method on a specified type to obtain an instance. This can support Singleton type hierarchies in an extensible manner. Therefore, implementation of a Singleton type hierarchy and its usage remains a technology specific issue.

Furthermore, if a single class variable is used in a classical Singleton implementation to hold the reference of the instance and it is exposed to subclasses via protected accessibility, then only one instance of that entire type hierarchy exists in the application. This is again a decision that should not rest with the implementation rather it should be ascertained from the domain. If the domain allows each class within a hierarchy of singletons to have an instance each (and no more), the implementation should support it. Adaptations to the classical Singleton implementation may allow this, for example, using a private instance variable for each class in the hierarchy or using an associative container in the base class mapping the concrete type to the instance. The SingletonHolder implementation [ Alexandrescu01 ] and the SingletonFactory discussed above provide this facility by default.

Substitutability is very strongly desired in singletons as coupled with dependency injection it enhances the testability of the dependant components. Substitutability has been implicitly discussed in the Singleton pattern via subclassing only. If singletons (classical or otherwise) implement abstract interfaces and there is support for dependency injection of these singletons, extensibility and testability of the dependant application can be enhanced considerably.

Injecting singletons

Dependency injection (DI) attempts to decouple dependants and dependencies by moving instantiation and initialisation of dependencies from the dependants to a DI framework component normally referred to as injector or container. Dependants identify their dependencies using identifiers which map to the specification of dependencies in the injector’s configuration. Thus, dependencies can simply be changed by altering the injector's configuration. Therefore, DI along with interface-based development has enhanced the configurability, extensibility and testability of object oriented software.

Some DI frameworks like Spring allow specification of a static method on a class, the execution of which returns an instance of that class. Thus Spring provides direct support for injecting classical Singleton objects into their dependants. If these Singleton classes implement an abstract interface, instantiating them via Spring provides all of the above abilities. Furthermore, restriction on instantiation within the classes ensures that even if a Spring injector is not used in some part of the application and a dependant attempts to obtain instances directly by calling static methods of these classes, the same instances of respective classes are returned.

Using a decoupled singleton instantiation mechanism like the SingletonFactory (Listing 1) with dependency injection may require obtaining an instance of the factory and then using the factory instance in the dependant to obtain the required singleton instance. As discussed earlier, this provides opportunities to extend SingletonFactory for specialised construction of individual singletons independently of their classes.

Singletons exist in context

In most cases, limiting the number of instances of a class within an application depends on the requirements of the application or a particular context in which the instance is required. For example, only one instance of a particular screen (e.g., an application configuration editor) is allowed within an application whereas many instances of other screens can be created. In other cases, infrastructure objects like network and database connections and logging utilities are singletons or multitons (e.g., the Logger class in log4j).

Thus, there may always be a requirement for limiting the number of instances of a class based on the requirements of the application. While such instances can be created at the application layer and passed to the corresponding modules or layers using PfA, the public accessibility of constructors of their classes poses a risk that a developer may instantiate a new object elsewhere in the system. Undetected, this can result in inconsistent operation of the system at best.

Thus, the requirement to control instantiation of specific classes is orthogonal to parameterisation from above. Singleton instances may still be created at the top layer and passed around via interfaces if a greater visibility of associations between dependants and dependencies is required. Restrictions on constructor invocation ensures that no unintended instances exist within the applications.

Therefore, if the instantiation of classes needs to be controlled, accessibility of constructors of these classes needs to be limited. Furthermore, the mechanism to return instances of such classes depends on the context in which these classes are being instantiated. The context should define the number of instances that can be created, the specific instance to be returned and the concrete type of the instance being returned. The rigid Singleton structure defined by the GoF does not provide such flexibility in object instantiation.

Revisiting Ignatchenko’s example flight simulator [ Ignatchenko12 ], not implementing the aircraft and engine as singletons allows the extension of this simulator to a multi-engine multi-aircraft application. However, some form of instance control is still needed in this example so that engines, for example, are instantiated only in the context of aircraft. This would allow only one engine for a single engined aircraft and two engines for a twin engined aircraft.

Contextualising instantiation

The context for a dependency is its dependants. A dependant should be able to specify or manage the instances of its dependencies. Considering the example of aircraft and engines mentioned above, if engines are dependencies of aircraft, the type and number of engines for a particular aircraft exist in the context of that aircraft. Thus, a single engine jet aircraft will have one jet engine but a twin piston engine aeroplane will have two piston engines.

In contrast, both the Singleton pattern as well as PfA consider dependency instantiation outside the context of the dependant. Singleton is especially suited if the context is the entire application rather than its finer components. PfA may be used to instantiate the required number and types of dependencies and populate the dependant objects only if the higher level layers have the contextual knowledge about the dependencies and the relationships between them and their dependants. This may, however, violate the principle of information hiding and introduce unintended coupling. GoF also describe a variant of Singleton that can return multiple instances of a given type in a controlled manner [ GoF94 ]. But that may also require the Singleton implementation to know about the relationships between the dependencies and dependants and may also make the instantiated dependencies accessible to objects other than the dependants. Thus it is not possible to ensure dependants to have exclusive ownership of singleton dependencies

This leads to a fundamental requirement of making the dependency construction mechanism accessible only to the corresponding dependants. Accessibility at this level of granularity is currently not available in most object oriented languages. In C++ this may be achieved via a friend relationship between dependencies and their dependants as in the SingletonHolder [ Alexandrescu01 ] implementation. Java does provide additional levels of access restrictions where protected and package-private members can only be accessed by classes within a package. However, it is possible to create the same package within a different project thereby circumventing these access restrictions and accessing such members of the same package in a different project. Scala can scope access restriction on a class to other packages enclosing the package containing that class. However, it suffers from the same accessibility loophole as Java. C# allows internal members to be accessible only by members from the same assembly or an assembly explicitly specified as the former’s friend. Relying only on these measures for controlling the access to dependency instantiation would require the dependants to be defined in specified packages for Java and Scala. In case of C#, reuse of dependencies may be severely restricted.

In managed languages such as Java and C#, private members can also be accessed via reflection. As using reflection to access private members is not considered good practice, it should not be used arbitrarily. Instead, dependency instantiation may be delegated to a factory as in the case of SingletonFactory above. The dependant (i.e., the context) and the factory hold references to each other. The context determines the type and the number of dependencies it needs and the factory creates those instances and injects them into the context. The context now holds references to its dependencies. It may make them available to other objects and manage their lifetimes as required. Finally, there may no longer be a need for static members to hold references to dependencies.

Figure 1 shows the class structure of a solution to the problem of instantiating engines for aircraft.

Figure 1

The Factory class implements the Injector interface. The inject method takes an instance of an implementation of the Context interface as the dependant and the type of the dependency to be created. The Factory instance creates this dependency instance and injects it into the dependant by calling the add method implementation. Listing 2 shows the code for Context and Injector interfaces and the Factory class.

public interface Context&lt;T&gt; {
  void add(T dependency);
  void setInjector(Injector&lt;T&gt; injector);
}
public interface Injector&lt;T&gt; {
  void inject(Context&lt;T&gt; dependant,Class&lt;T&gt; type)
         throws InvocationTargetException,
                IllegalAccessException,
                InstantiationException,
                NoSuchMethodException;
}
public class Factory&lt;T&gt; implements Injector&lt;T&gt;{
  private T getInstance(Class&lt;T&gt; type) throws
              InvocationTargetException,
              IllegalAccessException,
              InstantiationException,
              NoSuchMethodException{
    Constructor&lt;T&gt; constructor =
       type.getDeclaredConstructor();
    constructor.setAccessible(true);
    return (T) constructor.newInstance();
  }
  @Override
  public void
     inject(Context&lt;T&gt; dependant,Class&lt;T&gt; type)
        throws InvocationTargetException,
               IllegalAccessException,
               InstantiationException,
               NoSuchMethodException{
    dependant.add(getInstance(type));
  }
}
			
Listing 2
public abstract class Aircraft
   implements Context<Engine> {
  protected Map<String, Engine> engines;

  public Aircraft(){
    this.engines = new TreeMap<>();
  }
  public abstract void addEngines()
     throws Exception;
  public List<Engine> getEngines(){
    List<Engine> engineList = new LinkedList<>();
    for(Map.Entry<String, Engine> entry :
       this.engines.entrySet()){
    engineList.add(entry.getValue());
  }
  return engineList;
  }
}

public class SingleEnginePlane extends Aircraft {
  private Injector<Engine> injector;
  private final String id = "Main";
  @Override
  public void add(Engine dependency) {
    dependency.setId(id);
    this.engines.put(id, dependency);
  }
  @Override
  public void
     setInjector(Injector<Engine> injector) {
    this.injector = injector;
  }
  @Override
  public void addEngines() throws Exception{
    if (!this.engines.containsKey(this.id)){
      this.injector.inject(this, Engine.class);
    }
  }
}

public class TwinEnginePlane extends Aircraft {
  private final String leftEngineId =
     "Left Engine";
  private final String rightEngineId =
     "Right Engine";
  private Injector<Engine> injector;
  @Override
  public void add(Engine dependency) {
    if (!this.engines.containsKey
       (this.leftEngineId)){
      dependency.setId(this.leftEngineId);
      this.engines.put(this.leftEngineId,
                       dependency);
    } else if (!this.engines.containsKey
       (this.rightEngineId)){
      dependency.setId(this.rightEngineId);
      this.engines.put(this.rightEngineId,
                       dependency);
    }
  }
  @Override
  public void
     setInjector(Injector<Engine> injector) {
    this.injector = injector;
  }
  @Override
  public void addEngines() throws Exception {
    if (!this.engines.containsKey
       (this.leftEngineId)){
      this.injector.inject(this, Engine.class);
    }
    if (!this.engines.containsKey
       (this.rightEngineId)) {
      this.injector.inject(this, Engine.class);
    }
  }
}
public class Engine {
  ...
}
			
Listing 3

The Aircraft abstract class implements the Context interface and specifies methods relevant to aeroplanes in this example. It contains a map that holds the objects of the Engine class for a specific instance of the Aircraft class. The getEngines() method returns a list of Engine objects for the corresponding Aircraft instance. Two classes, SingleEnginePlane and TwinEnginePlane extend the Aircraft abstract class and implement the addEngines() method. The implementation in the SingleEnginePlane allows the instantiation of one object of the Engine class if none exists. The implementation in the TwinEnginePlane allows the instantiation of two objects of the Engine class if they do not exist already. These instantiations are performed using an instance of an Injector implementation, i.e., the Factory class in this case. Figures 2 and 3 show these interactions and the code for these classes is listed in Listing 3.

Figure 2
Figure 3

The following code snippet shows the usage of these classes,

  SingleEnginePlane plane1 =
     new SingleEnginePlane();
  TwinEnginePlane plane2 = new TwinEnginePlane();
  Factory&lt;Engine&gt; factory = new Factory&lt;&gt;();
  try{
    plane1.setInjector(factory);
    plane2.setInjector(factory);
    plane1.addEngines();
    plane2.addEngines();
    ...
  } catch (Exception exp){
    ...
  }

Hence, dependencies are only instantiated in the context implemented in the dependants. While Factory uses reflection to invoke private constructors of the specified classes, it only injects them into their dependants. Therefore, dependencies with restricted constructors cannot be instantiated using a Factory instance without a context. None of the participants here have any static variables nor are there any classical singletons within this structure.

Conclusions

The discussion above suggests that issues with the Singleton pattern arise from its structure which violates most key principles of effective object oriented design. The intent of this pattern, which is primarily to restrict the instantiation of a class to have only one instance, is largely unsupported in most programming languages. Scala offers object as a Singleton implementation. Some of the issues of the pattern can be resolved by altering its structure so that various orthogonal requirements of instance creation, lifetime management and concurrency are delegated to additional classes. If these additional classes support substitutability, requirement for different operating environments and applications may be supported. This leaves the class of which a singleton is to be instantiated to focus only on domain related functionality. Without the need for static variables in that class, its extensibility and substitutability may be considerably enhanced.

Singleton needs to be viewed as a broader issue of controlling instantiation of specified classes in the contexts in which their objects may be used. Contexts for such classes exist in their dependants and hence their dependants must be able to control the instantiation of these dependencies. Additionally, instance control can only be achieved by controlling the accessibility of constructors of respective classes. However, such fine grained accessibility that allows classes to specify other classes that may access their private members is not commonly available. In C++, this may be achieved via friend relationship between dependants and dependencies where as in managed languages like Java and C#, reflection may be exploited.

A structure in Java is discussed that uses a factory employing reflection to instantiate objects of classes that have private constructors. Dependants contain the context in which dependencies are to be instantiated and invoke a factory accordingly to obtain those instances. The factory instance uses a reference to the context (i.e., dependant) and injects the dependencies it instantiates directly into the associated dependant. This structure, while more complex than the classical Singleton structure, is flexible, extensible, testable and has better support for concurrency.

This reaffirms that implementing instance control or restriction is non-trivial at best and Singleton in this regard is only of limited use, i.e., enforcing a single instance of a class within an application. Instance control at finer granularities without language support requires structures more elaborate than the classical Singleton structure.

References

[Alexandrescu01] Andrei Alexandrescu, Scott Meyers and John Vlissides, Modern C++ Design: Applied Generic and Design Patterns (C++ in Depth) , Addison Wesley, 2001.

[Levine00] David L. Levine, Christopher D. Gill, Douglas C. Schmidt, Object Lifetime Manager, in Design Patterns in Communications edited by Linda Rising, Cambridge University Press, 2000, pp

[GoF94] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Design patterns : Elements of Reusable Object-Oriented Software , Addison Wesley, 1994.

[Hahsler04] Michael Hahsler, ‘A Quantitative Study of the Adoption of Design Patterns By Open Source Software Developers’ in Free/Open Source Software Development by Stefan Koch, IGI Publishing, pp103-124.

[Ignatchenko12] Sergey Ignatchenko, ‘Keep it Simple, Singleton!’ ACCU (Association of C and C++ Users) Overload #111, October 2012, pp 19–20.

[Kelly04] Allen Kelly, ‘The Encapsulate Context Pattern’ ACCU (Association of C and C++ Users) Overload #63, October 2004.

[Love06] Steve Love, ‘The Rise and Fall of Singleton Threaded’ ACCU (Association of C and C++ Users) Overload #73, June 2006, pp 18–21.

[Meyers04] Scott Meyers, Andrei Alexandrescu, ‘C++ and The Perils of Double-Checked Locking: Part I’ Dr Dobbs Journal , July 2004.

[Petersen13] Adam Petersen, ‘The Signs of Trouble: On Patterns, Humbleness and Lisp’ ACCU (Association of C and C++ Users) Overload #113, Feb 2013, pp 12-13.

[Radford03] Mark Radford, ‘ Singleton – The Anti-Pattern’ ACCU (Association of C and C++ Users) Overload #57, Oct 2003, pp 20-22.

[Schmidt97] Douglas Schmidt, Tim Harrison, Double-Checked Locking-An Optimisation Pattern for Efficiently Initialising and Accessing Thread-safe Objects, Pattern Languages for Program Design 3 , edited by Robert Martin, Frank Buschmann and Dirke Riehle, Addison Wesley, 1997.

[Stencel08] Krzysztof Stencel and Patrycja Wegrzynowicz, ‘Implementation Variants of the Singleton Design Pattern’ OTM 2008 Workshops LNCS 5333, pp 396–406, Springer-Verlag, 2008






Your Privacy

By clicking "Accept Non-Essential Cookies" you agree ACCU can store non-essential cookies on your device and disclose information in accordance with our Privacy Policy and Cookie Policy.

Current Setting: Non-Essential Cookies REJECTED


By clicking "Include Third Party Content" you agree ACCU can forward your IP address to third-party sites (such as YouTube) to enhance the information presented on this site, and that third-party sites may store cookies on your device.

Current Setting: Third Party Content EXCLUDED



Settings can be changed at any time from the Cookie Policy page.