Singleton Design Pattern 7/1/2016 1 CS 631: Singleton Design Pattern

advertisement
Singleton Design Pattern
7/1/2016
CS 631: Singleton Design Pattern
1
Outline
• Singleton’s Description
• Design
– Class diagram
• Application
– Market class
• Implementation
– Basic
– Destroying singleton
7/1/2016
CS 631: Singleton Design Pattern
2
Description
• Intent
– To ensure that a class has only one instance and provide a
global point of access to it.
• Applicability
– Use when there must be exactly one instance of a class,
and it must be accessible to clients from a well-known
access point.
• Benefits
– Controlled access to sole instance
– Reduced name space (avoids polluting the name space
with global variables)
– Permits a variable number of instances.
7/1/2016
CS 631: Singleton Design Pattern
3
Class Diagram
7/1/2016
CS 631: Singleton Design Pattern
4
Market Class
• Market class describes the state of the market at any
time point.
• In its simplest form it can provide an interest rate for
any given time interval (maturity).
• Consider an application that evaluates various
financial instruments in real time.
– All evaluations are performed based on market
conditions.
– Market data should be consistent for all evaluations.
• A single market object is required by all modules.
Hence it should be implemented as a Singleton.
7/1/2016
CS 631: Singleton Design Pattern
5
Implementation
• The description is simple, but implementation issues
are complicated.
• A singleton is an improved global variable in that
one cannot create a secondary object of singleton
type.
• From a client standpoint the Singleton object owns
itself, which means that it is responsible for creating
and destroying itself.
• Managing a singleton's lifetime causes the most
implementation difficulties.
7/1/2016
CS 631: Singleton Design Pattern
6
Static Implementation
class Market
{
public:
static double getRate(double maturity)
{
return rates[maturity];
}
private:
static map<double,double>
refreshRates() {...}
static map<double,double> rates;
};
map<double,double>
Market::rates = refreshRates();
7/1/2016
CS 631: Singleton Design Pattern
7
Static Implementation: Usage
int main()
{
cout << Market::getRate(1.0)
<< " "
Market::getRate(0.5) << endl;
return 0;
}
7/1/2016
CS 631: Singleton Design Pattern
8
Static Implementation: Disadvantages
• Static functions cannot be virtual!
– Cannot change behavior by inheriting from the class.
• No central point of initialization or cleanup.
– Makes it difficult to create market based on different
sources of data.
– Makes it difficult to release any resources before the end
of the program.
7/1/2016
CS 631: Singleton Design Pattern
9
Basic Implementation
class BasicMarket
{
public:
// unique point of access
static BasicMarket& getInstance()
{
if (! instance)
{
instance = new BasicMarket();
instance->refreshRates();
}
return *instance;
}
double getRate(double maturity)
{
return rates[maturity);
}
7/1/2016
CS 631: Singleton Design Pattern
10
Basic Implementation (cont.)
private:
BasicMarket() {}
BasicMarket(const BasicMarket&) {}
BasicMarket& operator=(const BasicMarket&);
~BasicMarket();
// refresh rates data
void refreshRates();
static BasicMarket* instance;
map<double, double> rates;
};
BasicMarket*
BasicMarket::instance = 0;
7/1/2016
CS 631: Singleton Design Pattern
11
Basic Implementation: Discussion
• Advantages
– User code cannot create singletons.
– If it's never used, no object is created at the cost of the
null test (usually negligible).
– Returning a reference from getInstance() prevents clients
from trying to delete an object.
– Disabling the assignment operator prevents from
assigning objects.
– Making the destructor private prevents the clients that
hold the pointer to BasicMarket from accidentally
deleting it.
• Disadvantage
– Destruction of the object is not controlled.
7/1/2016
CS 631: Singleton Design Pattern
12
Destroying the Singleton
• When singleton acquires any resources, such as
network connections, etc.; not destroying it properly
will lead to a resource leak.
• The Singleton should be deleted during the
application's shutdown after the use by any modules.
• Meyers singleton uses a local static variable.
– initialized when the control flow is first passing its
definition.
– the compiler generates code so that after initialization, the
variable is registered for destruction.
7/1/2016
CS 631: Singleton Design Pattern
13
Meyers Singleton
class LocalMarket
{
public:
static LocalMarket& getInstance()
{
static LocalMarket instance;
return instance;
}
double getRate(double maturity) {...}
private:
LocalMarket() {refreshRates();}
LocalMarket(const LocalMarket&) {}
LocalMarket& operator=
(const LocalMarket &);
~LocalMarket();
void refreshRates();
map<double, double> rates;
};
7/1/2016
CS 631: Singleton Design Pattern
14
Meyers Singleton: Compiler Code
static LocalMarket& LocalMarket::getInstance()
{
// compiler-generated functions and variables
extern void __ConstructSingleton(void* memory);
extern void __DestroySingleton();
static bool __initialized = false;
static char __buffer[sizeof(LocalMarket)];
if (!__initialized)
{
__ConstructSingleton(__buffer);
// register destruction
atexit(__DestroySingleton);
__initialized = true;
}
return *reinterpret_cast<LocalMarket*>(__buffer);
}
7/1/2016
CS 631: Singleton Design Pattern
15
Download