Friday, October 14, 2005

Singleton Duplicity in 5 Minutes

Once you've finished laughing at the tongue-in-check title of this post, you can read on for a discussion of the Singleton Pattern. This is not meant to be an all-inclusive resource for Singleton development, but rather to provide a birds-eye view of what the pattern is all about, and one (extremely quick) way to implement it in C#.


Note that the Singleton is a design pattern, which means it is not language specific. I use C# in my code examples simply out of personal preference; however you can implement this pattern using just about any object-oriented language.



What is a Singleton?

In the simplest terms, a Singleton is a class for which there is only a single shared instance. Any code that accesses the class uses the same instance of the object. Consequently, Singletons must provide a global point of access to their instance.



Why use a Singleton?

Think about your computer. There are certain shared resources of which there can only be one. For example, your computer has a single keyboard that is used by all of your applications. You probably (but not necessarily) have only one mouse. From a software standpoint, your Operating System can reasonably have only one process manager.



Sometimes there are programmatic situations that require one and only one of something, too. A great example of this is a logging service. A logging service only needs to exist in memory one time, and that instance can be shared across all functionality that needs to log an event.



Quick and Dirty C# Singleton

Here's an example of an extremely basic Singleton class. In the real world, you'll want to make sure that any Singleton class is thread safe, but the intent here is to simply provide an overview of the basic Singleton framework.


public class Singleton
{
private static Singleton instance;

private Singleton()
{
}

public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}

public string SayHello()
{
return "Hello World!";
}
}

In the example above, you'll notice that the constructor is private rather than public. This prevents the class from being instanciated. Because the constructor uses the "private" access modifier, it is inaccessible to any code outside of the Singleton class. But, since a private method (and the constructor is simply a method) is accessible from within the same class, code within that class can create an instance of it. In this way, we force all access to the object to go through the GetInstance method, which will return the static (shared) instance.



To use the object above, you might have code that looks something like this:

Singleton mySingleton = Singleton.GetInstance();
string helloMessage = mySingleton.SayHello();
mySingleton = null;

Note that although the reference to the Singleton instance is destroyed when the local object is made null, the instance itself remains, and can be reused by subsequent calls to the GetInstance method. In the first example, note that the instance variable is private, so it is not implicitly accessible to code outside the Singleton class.



Other Considerations

There are multiple ways to implement the Singleton Pattern. The code provided here is merely an example of one implementation method to facilitate discussion of the pattern itself.



If you're planning on implementing the Singleton pattern, do so with care. There are some in the industry who refer to a Singleton as an anti-pattern because it is so often misused. Make sure any objects that interract with singletons are still loosely coupled, and that you're not using a Singleton simply as a global variable.



For more information on Singletons, visit these resources:

No comments: