Introduction
This is a short article series (articles being short and series being long) about design patterns. Design patterns are, as per my best understanding, a pair of problem and a solution for a given situation.
Let’s take an example from the computing world.
Problem and Situation: I want to search an array. It is given that the array is sorted.
Solution: Use Binary Search, because it will be faster.
Similarly a design pattern example could be...
Problem and Situation: I want only one instance of the given object in my system. This is required because the class represents my log file and will be accessed from multiple sources. Hence to avoid any race condition, I want to have only one instance of the class. In this case, because there exists an object, a static
class will not make sense.
Solution: Use a singleton.
Why this Article Series will be Different
There are countless number of articles on the web on design patterns, so why would anyone want to read this? The reason is that in this series I will try to be more practical than abstract and it will be .NET C# driven hence even using language features to help implement the patterns. The treatment of the subject will be more examples oriented than abstract. Further, we will do what makes sense, if code is the best way to explain something then it's code, and if it needs complex state machines then it will be state machines.
Patterns are usually classified as design patterns and architecture patterns. Design patterns typically deal with problems localised into a subcomponent or a use case of the entire application, for example how do I implement my hierarchical help. Their application provides a readily available set of types which can be coded. Architecture patterns have a larger scope and provide guidelines for project. They end up providing the blue print against which a design will be done.
Design Pattern Types
According to the Gang of four book vis Design Patterns: Elements of Reusable Object-Oriented Software, patterns (GOF) may be classified into:
Creational Patterns – The creational patterns talk about how to create a new object, where do I write new in my code? Some of the magic they allow us to perform are having just one instance of a class using a singleton pattern; allow creating a heavy object using prototype and so on.
Structural Patterns – The structural patterns talk about how to create an object should I use inheritance, composition. In other words, how do I compose my elements to create a better class? Some of the magic they allow us to do is create an object whose hierarchy of classes and sub classes is dynamic using Decorator, creating a large number of similar objects using fly weight and so on.
Behavioural Patterns – These patterns deal with how objects communicate or in other words if I want to call a method of an object how do I do it. They allow neat magic like giving a class a new method without changing its code. Giving a general algorithm while requesting exact implementations for providing some specific logic for example sorting requires two loops but the < sign has to be provided by the exact implementation.
In this series, we will look into the GOF patterns and then other patterns which are not in GOF such as resurrection.
Pattern of the Day: Singleton
This is a creational pattern - it deals with how I create a new object. The Singleton pattern guarantees that only one instance of the class will be made available in the entire execution context or app domain.
Singleton is different from static
where there is no instance.
How to do it without singleton?
Let's first try to create and maintain only one instance of the class without using Singleton.
public static MyClass myClass = null;
public class MyClass()
{
}
public class MyUsageClass
{
if(myClass == null)
{
myClass = new MyClass();
}
}
There are a number of issues with this approach. For example, what if I need to maintain sync locks while creation of object, in that case the logic of this creation will be distributed all across the place. What if I want to run some special code before and after the instance is created and so on.
How To Do It In .NET
public class MyClass
{
private static MyClass myClass = null;
private MyClass()
{
}
public static MyClass GetInstance()
{
if(MyClass.myClass == null)
{
MyClass.myClass = new MyClass();
}
return MyClass.myClass;
}
public static MyClass GetInstance
{
get
{
if (MyClass.myClass == null)
{
MyClass.myClass = new MyClass();
}
return MyClass.myClass;
}
}
}
The singleton way of doing things makes life a little simple. There exists a static
instance of the class which is managed by the class itself.
To ensure no one can instance the class, we make the constructor private
. There exists a method called GetInstance
which the instance on the first use and returns the class. A similar job is done by the property GetInstance
. Thus it is at designer's discussion to use one of the said techniques.
If it is required the constructor be thread safe, then code of the following structure may be used.
object locker = new object();
private MyClass()
{
lock (locker)
{
}
}
The constructor is still responsible for creating a nice instance with all initialization done.
How Do I Pass Parameters?
I had been taking a session on singleton and someone asked me what if we need to pass parameters to the class during instantiation. If it occurs that you need to pass parameters to the instantiation logic, then this is not a case for singleton. This is because the class depends on some external conditions and hence a single instance will not suffice it’s working.
Any attributes required by a singleton should be made available using deployment time in a configuration.
Some Usage Scenarios of Singleton
Singletons can be used in a variety of scenarios, some of them include representing a physical resource like log files, network cards, and so on.
History
- 2nd December, 2010: Initial post