singleton design pattern
implementation in C++
Singleton is one
of the commonly used patterns in object oriented developments. In this article
I am discussing abt this pattern in general and how we can implement this
pattern with C++.
Introduction
Suppose we have
to use a single object of a class throughout the lifetime of an application. In
C++, it is possible to declare a global object, which can be used anywhere
inside the program. But a good object oriented design strictly prohibits the
use of global variables or methods, since they are against the fundamental
principles of object orientation like data encapsulation or data hiding. More
over, most latest object oriented programming languages like JAVA or C# do not
support global variables or functions.
Another practical
solution to get a single object is by declaring a class, which contains only
static methods. A static class is loaded into memory when the execution of the
program starts and it remains there till the application ends. Remember that
for invoking a static method of a class, it is not necessary to create an
instance of the class. But remember that a class with only static methods and
variables are not a good object oriented design. A class of static methods
unfortunately breaks down to a list of functions or utilities.
When we want to
create only one instance of a class in a truly object oriented fashion by
adhering to the basic principles of object oriented programming, the Singleton
patterns are used. The Singleton Pattern comes under that classification of
Creational Pattern, which deals with the best ways to create objects. The
Singleton Design pattern is used, where only one instance of an object is
needed throughout the lifetime of an application. The Singleton class is instantiated
at the time of first access and same instance is used thereafter till the
application quits.
There are very
good non-software examples available in real world for Singleton patterns. The
office of the Principal of my college is a Singleton. The University specifies
the means by which a principal is selected, limits the term of office, and
defines the order of succession. As a result, there can be at most one active
principal at any given time. Regardless of the personal identity of the
principal, the title, "The Principal" is a global point of access
that identifies the person in the office.
The Singletons
are often used to control access to resources such as database connections or
sockets. Suppose we have a license for only one connection for our database. A
Singleton connection object makes sure that only one connection can be made at
any time.
It is pretty easy
to implement the Singleton Pattern in any object oriented programming languages
like C++, JAVA or C#. There are lots of different ways to implement the
Singleton Pattern. But by using a private constructor and a static method to
create and return an instance of the class is a popular way for implementing
Singleton Pattern. The UML representation of a Singleton Pattern is shown
below.
The Singleton
design pattern ensures only one instance of a class in an application (more
generally it provides a framework to control the instantiations of a particular
class, so that more than one instantiation could be provided, but under the
control of the Singleton class). The GoF book discusses Singleton patterns,
while Meyers discusses general techniques for limiting object instantiation in
item 26 of More Effective C++. In Singleton classes, all of the regular
constructors are publicly disabled (put in the private section), and access to
the singleton object is through a static method which creates a controlled
instance of the class and returns a reference to this controlled instance.
An example that
Meyers uses is:
class Printer {
public:
static
Printer& thePrinter();
// ...
private:
Printer();
// no public creation of Printer objects
Printer
(const Printer& rhs);
//
...
};
Printer&
Printer::thePrinter() {
static Printer p;
return
p;
}
// example usage:
Printer::thePrinter().reset();
Printer::thePrinter().submitJob(buffer);
Note that this
example implementation code will not work if the Singleton is accessed in a
multi-threaded environment, since there may be two (or more) threads trying to
simultaneously access the Singleton for the first time, causing a conflict in
the static instance creation. Some form of mutex protection must be provided in
this scenario.
There are many
flavors of Singletone and quite a few subtle complexities, although the general
principle of the pattern makes it one of the easiest to understand. One
potential complexity is controlled destruction of the internal Singleton
instance (i.e. when is it destructed and in what order compared to other
Singletons or global objects).
Example:
No comments:
Post a Comment