📄 pat3e-1.htm
字号:
<SCRIPT>
function setFocus() {
if ((navigator.appName != "Netscape") && (parseFloat(navigator.appVersion) == 2)) {
return;
} else {
self.focus();
}
}
</SCRIPT><HTML><HEAD> <TITLE>Singleton</TITLE></HEAD>
<BODY BGCOLOR = #FFFFFF
TEXT = #000000
onLoad="setFocus()";
>
<A NAME="top"></A>
<A NAME="Singleton"></A>
<A NAME="intent"></A>
<H2><A HREF="#motivation"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Motivation"></A> Intent</H2>
<A NAME="auto1000"></A>
<P>Ensure a class only has one instance, and provide a global point
of access to it.</P>
<A NAME="motivation"></A>
<H2><A HREF="#applicability"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Applicability"></A> Motivation</H2>
<A NAME="auto1001"></A>
<P>It's important for some classes to have exactly one instance.
Although there can be many printers in a system, there should be only
one printer spooler. There should be only one file system and one
window manager. A digital filter will have one A/D converter. An
accounting system will be dedicated to serving one company.</P>
<A NAME="auto1002"></A>
<P>How do we ensure that a class has only one instance and that the
instance is easily accessible? A global variable makes an object
accessible, but it doesn't keep you from instantiating multiple
objects.</P>
<A NAME="auto1003"></A>
<P>A better solution is to make the class itself responsible for keeping
track of its sole instance. The class can ensure that no other
instance can be created (by intercepting requests to create new
objects), and it can provide a way to access the instance. This is
the Singleton pattern.</P>
<A NAME="applicability"></A>
<H2><A HREF="#structure"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Structure"></A> Applicability</H2>
<A NAME="auto1004"></A>
<P>Use the Singleton pattern when</P>
<UL>
<A NAME="auto1005"></A>
<LI>there must be exactly one instance of a class, and it must be
accessible to clients from a well-known access point.</LI>
<A NAME="auto1006"></A>
<P></P>
<A NAME="auto1007"></A>
<LI>when the sole instance should be extensible by subclassing, and
clients should be able to use an extended instance without
modifying their code.</LI>
</UL>
<A NAME="structure"></A>
<H2><A HREF="#participants"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Participants"></A>
Structure</H2>
<P ALIGN=CENTER><IMG SRC="singl014-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/Pictures/singl014.gif"></P>
<A NAME="participants"></A>
<H2><A HREF="#collaborations"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Collaborations"></A>
Participants</H2>
<UL>
<A NAME="auto1008"></A>
<LI><B>Singleton</B></LI>
<A NAME="auto1009"></A>
<P></P>
<UL>
<A NAME="auto1010"></A>
<LI>defines an Instance operation that lets clients access its
unique instance. Instance is a class operation (that is, a class
method in Smalltalk and a static member function in C++).</LI>
<A NAME="auto1011"></A>
<P><!-- extra space --></P>
<A NAME="auto1012"></A>
<LI>may be responsible for creating its own unique instance.</LI>
</UL>
</UL>
<A NAME="collaborations"></A>
<H2><A HREF="#consequences"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Consequences"></A> Collaborations</H2>
<UL>
<A NAME="auto1013"></A>
<LI>Clients access a Singleton instance solely through Singleton's
Instance operation.</LI>
</UL>
<A NAME="consequences"></A>
<H2><A HREF="#implementation"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Implementation"></A> Consequences</H2>
<A NAME="auto1014"></A>
<P>The Singleton pattern has several benefits:</P>
<OL>
<A NAME="auto1015"></A>
<LI><EM>Controlled access to sole instance.</EM>
Because the Singleton class encapsulates its sole instance, it can
have strict control over how and when clients access it.</LI>
<A NAME="auto1016"></A>
<P></P>
<A NAME="auto1017"></A>
<LI><EM>Reduced name space.</EM>
The Singleton pattern is an improvement over global variables. It
avoids polluting the name space with global variables that store sole
instances.</LI>
<A NAME="auto1018"></A>
<P></P>
<A NAME="auto1019"></A>
<LI><EM>Permits refinement of operations and representation.</EM>
The Singleton class may be subclassed, and it's easy to configure an
application with an instance of this extended class. You can
configure the application with an instance of the class you need at
run-time.</LI>
<A NAME="auto1020"></A>
<P></P>
<A NAME="auto1021"></A>
<LI><EM>Permits a variable number of instances.</EM>
The pattern makes it easy to change your mind and allow more than one
instance of the Singleton class. Moreover, you can use the same
approach to control the number of instances that the application uses.
Only the operation that grants access to the Singleton instance needs
to change.</LI>
<A NAME="auto1022"></A>
<P></P>
<A NAME="auto1023"></A>
<LI><EM>More flexible than class operations.</EM>
Another way to package a singleton's functionality is to use class
operations (that is, static member functions in C++ or class methods
in Smalltalk). But both of these language techniques make it hard to
change a design to allow more than one instance of a class. Moreover,
static member functions in C++ are never virtual, so subclasses can't
override them polymorphically.</LI>
</OL>
<A NAME="implementation"></A>
<H2><A HREF="#samplecode"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: Sample Code"></A> Implementation</H2>
<A NAME="auto1024"></A>
<P>Here are implementation issues to consider when using the Singleton
pattern:</P>
<OL>
<A NAME="auto1025"></A>
<LI><EM>Ensuring a unique instance.</EM>
The Singleton pattern makes the sole instance a normal instance of a
class, but that class is written so that only one instance can ever be
created. A common way to do this is to hide the operation that
creates the instance behind a class operation (that is, either a
static member function or a class method) that guarantees only one
instance is created. This operation has access to the variable that
holds the unique instance, and it ensures the variable is initialized
with the unique instance before returning its value. This approach
ensures that a singleton is created and initialized before its first
use.
<A NAME="single-cpp-imp"></A>
<P>You can define the class operation in C++ with a static member
function <CODE>Instance</CODE> of the <CODE>Singleton</CODE> class.
<CODE>Singleton</CODE> also defines a static member variable
<CODE>_instance</CODE> that contains a pointer to its unique instance.
<A NAME="auto1026"></A>
<P>The <CODE>Singleton</CODE> class is declared as
<A NAME="auto1027"></A>
<PRE>
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
</PRE>
<A NAME="auto1028"></A>
<P>The corresponding implementation is</P>
<A NAME="auto1029"></A>
<PRE>
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance () {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}
</PRE>
<A NAME="auto1030"></A>
<P>Clients access the singleton exclusively through the <CODE>Instance</CODE>
member function. The variable <CODE>_instance</CODE> is initialized to 0,
and the static member function <CODE>Instance</CODE> returns its value,
initializing it with the unique instance if it is 0. <CODE>Instance</CODE>
uses lazy initialization; the value it returns isn't created and stored
until it's first accessed.</P>
<A NAME="auto1031"></A>
<P>Notice that the constructor is protected. A client that tries to
instantiate <CODE>Singleton</CODE> directly will get an error at
compile-time. This ensures that only one instance can ever get
created.</P>
<A NAME="auto1032"></A>
<P>Moreover, since the <CODE>_instance</CODE> is a pointer to a Singleton
object, the <CODE>Instance</CODE> member function can assign a pointer to
a subclass of Singleton to this variable. We'll give an example of
this in the Sample Code.</P>
<A NAME="auto1033"></A>
<P>There's another thing to note about the C++ implementation. It
isn't enough to define the singleton as a global or static object and
then rely on automatic initialization. There are three reasons for
this:</P>
<OL>
<A NAME="auto1034"></A>
<LI>We can't guarantee that only one instance of a static object
will ever be declared.</LI>
<A NAME="auto1035"></A>
<P></P>
<A NAME="auto1036"></A>
<LI>We might not have enough information to instantiate every singleton at
static initialization time. A singleton might require values that are
computed later in the program's execution.</LI>
<A NAME="auto1037"></A>
<P></P>
<A NAME="auto1038"></A>
<LI>C++ doesn't define the order in which constructors for global objects
are called across translation units [<A HREF="bibfs-1.htm#c++_arm" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#c++_arm" TARGET="_mainDisplayFrame">ES90</A>]. This means
that no dependencies can exist between singletons; if any do, then
errors are inevitable.</LI>
</OL>
<A NAME="auto1039"></A>
<P>An added (albeit small) liability of the global/static object approach
is that it forces all singletons to be created whether they are used
or not. Using a static member function avoids all of these problems.</P>
<A NAME="auto1040"></A>
<P>In Smalltalk, the function that returns the unique instance is
implemented as a class method on the Singleton class. To ensure that
only one instance is created, override the <CODE>new</CODE> operation.
The resulting Singleton class might have the following two class
methods, where <CODE>SoleInstance</CODE> is a class variable
that is not used anywhere else:</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -