Introduction
Singleton ------- Creational Design pattern
Use the Singleton Pattern when:
- There must be exactly one instance of a class, and it must be accessible to clients from a well-known access point.
- When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.
Example
The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. It is named after the singleton set, which is defined to be a set containing one element. The office of the President of the United States is a Singleton. There can be at most one active president at any given time. Regardless of the personal identity of the active president, the title, "The President of the United States" is a global point of access that identifies the person in the office.
Singleton Code
Make the class of the single instance object responsible for creation, initialization, and access. Declare the instance as a private static data member. Provide a public static member function that encapsulates all initialization code, and provide access to the instance.
class Singleton {
private static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton GetInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
public void WriteSomething() {
Console.WriteLine("Singleton.WriteSomething() running" );
}
}
Revision 1.1
Since the above code is not thread safe, and from the users' comments, I have decided to make it thread safe. Hope this helps. Here is the code for the thread-safe Singleton, the one which works in a multi-threaded environment.
namespace ThreadSafeSingleTon
{
public sealed class TSSingleton
{
private static volatile TSSingleton instance = null;
private static object syncObj = new object();
private TSSingleton()
{
}
public static TSSingleton Instance
{
get
{
if (instance == null)
{
lock(syncObj)
{
if (instance == null)
instance = new TSSingleton();
}
}
return instance;
}
}
}
}
using System.Diagnostics;
As you can see, this class is similar in structure to the Singleton
class. The instance member variable is no longer set at creation time, but in the Instance
property instead. The instance
variable is declared to be volatile in order to assure that the assignment of instance is complete before the instance can be accessed.
The syncObj
object is used to lock on. The lock ensures that only one thread can access the instance creation code at once. That way, you won't get into a situation where two different threads are trying to create the singleton simultaneously.
Abstract Factory ---- Creational Pattern
Trying to maintain portability across multiple platforms requires lots of preprocessor "case" statements. The Factory pattern suggests defining a creation services interface in a factory base class, and implementing each platform in a separate Factory derived class. If an application is to be portable, it needs to encapsulate platform dependencies. These "platforms" might include: windowing system, operating system, database, etc. Too often, this encapsulation is not engineered in advance, and lots of #ifdef
case statements with options for all currently supported platforms begin to procreate like mushrooms throughout the code.
Abstract Factory simplifies the creation of different classes of same family by providing with a Contract. It is like saying ‘to enter United states, you need to agree with the contract’.
Abstract Factory Code
using System;
using System.Diagnostics;
namespace abstractfact{
abstract class MainWindow {
abstract public void draw();
};
class UnixSystem : MainWindow {
override public void draw() { Console.WriteLine("UnixSystem");}
};
class WindowsSystem : MainWindow {
override public void draw() { Console.WriteLine("WindowsSystem"); }
};
abstract class Factory {
abstract public MainWindow whichSystem();
};
class UnixFactory : Factory {
override public MainWindow whichSystem() {return new UnixSystem(); }
};
class WindowsFactory :Factory {
override public MainWindow whichSystem() { return new WindowsSystem(); }
};
class SimilarWindows {
private MainWindow mainWind;
public SimilarWindows( Factory factory ){
mainWind = factory.whichSystem();
}
public void Run()
{
mainWind.draw();
}
}
class AbstractImpl
{
[STAThread]
static void Main(string[] args)
{
#if UNIX
Factory factory = new UnixFactory();
#else
Factory factory = new WindowsFactory();
#endif
MainWindow w = factory.whichSystem();
w.draw();
SimilarWindows s = new SimilarWindows(factory);
s.Run() ;
}
}
}
The Factory pattern suggests defining a creation services interface in a Factory
base class, and implementing each "platform" in a separate Factory derived class.
More design patterns will be posted soon...