-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsingleton.tex
More file actions
241 lines (199 loc) · 11.1 KB
/
Copy pathsingleton.tex
File metadata and controls
241 lines (199 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
\chapter{The Singleton pattern}
``Singleton'' always sounded to me like the name of some small American town,
maybe one where nobody ever gets married. But it's actually the name of our
first (and easiest) \textit{design pattern}, and the subject of this chapter.
\section{Design pattern}
You know how when you sit down to write some code, there are times when you
think, ``wait, I've written this before''? Programmer's d\'{e}j\`{a} vu is
commonplace, especially because certain tips and tricks end up working in a lot
of different settings. For example, we've all seen how to go through an array
and add up all its elements, or find its maximum value, or check whether it
contains a particular item. You might think of these as ``programming
patterns.'' They're bite-sized, go-to solutions that can handle a myriad of
common little programming scenarios.
It turns out that the same is true of design. Certain motifs in how classes
collaborate with each other crop up again and again in different settings.
They're important enough that they've been identified, described, and named.
\index{design pattern}
\index{Gamma, Erich}
\index{Vlissides, John}
\index{Johnson, Ralph}
\index{Helm, Richard}
\index{gang of four@the ``Gang of Four''}
The people who first promoted the idea of \textbf{design patterns} were Erich
Gamma, John Vlissides, Ralph Johnson, and Richard Helm, who were thereafter
nicknamed ``The Gang of Four.'' (You'll hear many references in the software
development industry to a ``Gang of Four design pattern,'' sometimes
abbreviated ``GoF design pattern.'' This means one of the 21 named patterns
that appeared in their hugely influential 1994 book \textit{Design Patterns:
Elements of Reusable Object-Oriented Software}. It's a book highly worth
obtaining and reading.)
One thing that's great about this is that just by mentioning one of these
agreed-upon pattern names -- like ``Observer,'' ``Iterator,'' or ``Strategy'' --
every developer worth their salt will instantly conjure up in their mind the
mechanics of that particular pattern, and know immediately what kind of
problem it's intended to solve. It saves a lot of words trying to describe an
idea you know your fellow developer has seen before, if only you could get
them to realize what you're talking about.
In this brief chapter, we'll cover the simplest GoF pattern of all:
the \textbf{Singleton} pattern.
\section{The Singleton pattern}
\index{Singleton pattern}
\index{design pattern!Singleton}
The Singleton pattern is so simple it almost doesn't even deserve to be called
a pattern. But it is. And it's easy to figure out when it applies to your
situation: \textbf{a Singleton is used when you have a class for which you
only ever want to instantiate one object.}
If you think about it, this kind of situation is pretty rare. Clearly any
relevant program is going to need to instantiate lots of different
\texttt{Car} objects, or \texttt{Ballplayer}s, or \texttt{Professor}s. There
are occasions, though, when your class isn't so much a category as it is a
special, one-of-a-kind object. Here are some examples:
\begin{itemize}
\itemsep.1em
\index{printerManager@\texttt{PrinterManager}}
\item Part of your operating system may have a \texttt{PrinterManager} class
that controls sending documents to various printers. The code will create many
\texttt{Printer} objects, and many \texttt{Document}s, but only one
\texttt{PrinterManager} which runs traffic control and routes print jobs to
available printers.
\index{database@\texttt{Database}}
\item Your website that collects information about classic rock 'n' roll
albums may have a \texttt{Database} class that represents the underlying data
storage. You might get multiple \texttt{Connection}s to it and instantiate
multiple \texttt{Query} objects to search it, but there's just one
\texttt{Database} as a point of contact.
\index{configuration@\texttt{Configuration}}
\item Most programs have some way of configuring them, usually by tweaking the
values of various configuration variables. Your program could have a
\texttt{Config\-uration} class from which the other software components can
fetch the values of the settings as needed. There needs to be only
\textit{one} \texttt{Configuration} object, since they will all share access
to a common set of settings.
\end{itemize}
\index{instantiation}
\index{global point of access}
The Singleton pattern does two things: (1) it ensures that only one
instantiation is possible, and (2) it provides a global point of access to
that one object, so that the rest of the code can get to it.
\section{Implementation}
Figure~\ref{fig:singletonCode} (p.~\pageref{fig:singletonCode}) shows what a
properly-coded Singleton pattern looks like. It uses the \texttt{Configuration}
example from above. Let's go through each part carefully.
\begin{figure}[ht]
\centering
\begin{Verbatim}[fontsize=\footnotesize,samepage=true,frame=single]
class Configuration {
private static Configuration theInstance;
public static synchronized Configuration instance() {
if (Configuration.theInstance == null) {
Configuration.theInstance = new Configuration(...);
}
return Configuration.theInstance;
}
private Configuration(...) {
...
}
// The actual methods of the object. For Configuration, this
// might include something like:
public String getParamSetting(String param) {
...
}
}
\end{Verbatim}
\caption{A properly-coded Singleton pattern.}
\label{fig:singletonCode}
\end{figure}
\index{static@\texttt{static}}
\index{theInstance@\texttt{theInstance}}
Let's go through each part carefully. First, we have a
\textit{\texttt{static}} variable called ``\texttt{theInstance}''. Recall that
\texttt{static} here means ``goes with the class as a whole, rather than with
each individual object.'' The reason for this is \textit{the class itself will
be holding on to its one-and-only instantiated object.} This is one of the few
places we'll be using \texttt{static} stuff in this book, because we need to.
If \texttt{theInstance} were \textit{not} \texttt{static}, then the only way
to get a hold of \texttt{theInstance} would be to have an instance of
\texttt{Configuration} in the first place...which would defeat the purpose of
the pattern.
\index{private@\texttt{private}}
Note that \texttt{theInstance} is also marked \texttt{private}. This is
partially because of our rule ``all inst vars should always be private,
period,'' but also because making this variable accessible outside the class
would make the whole pattern collapse. Parts of the code that needed access to
the \texttt{Configuration} singleton instance would try to grab
\texttt{theInstance} and use it, but it might not have even been set to
anything yet!
\index{instance@\texttt{.instance()}}
Next, we have the \texttt{instance()} method. This method is also
\texttt{static}, so that it can be called on the \textit{class} rather than on
an object. And what does it return? A \texttt{Configuration} object...or
perhaps I should say, \textit{the} \texttt{Configuration} object since there's
only ever going to be one.
\index{public@\texttt{public}}
\index{package visibility}
Unlike \texttt{theInstance}, \texttt{instance()} is public. (Package-level
visibility may also be an appropriate choice, depending on how wide your
intended users of this Singleton are.) This is part of the public interface of
the class, designed to be called by code external to the class.
\index{thread}
\index{multithreaded program}
\index{synchronized@\texttt{synchronized}}
The other word on the declaration line -- \texttt{synchronized} -- is probably
foreign to you. Its purpose is beyond the scope of this chapter. Very briefly,
``\texttt{synchronized}'' prevents two different \textbf{threads} of execution
from entering the \texttt{.instance()} method at the same time. A
\textbf{multithreaded program} is one that executes more than one flow of
control simultaneously, each with its own stack. It turns out that if more than
one thread was inside this method at the same time, we might accidentally
instantiate \textit{two} (or more) \texttt{Configuration} objects. For our
single-threaded programs this isn't an issue, but it's good practice to get in
the habit of making your Singleton \texttt{instance()} methods synchronized.
Now let's dive in to the code for \texttt{instance()}. It's very simple, as
you'll see: all it does is say ``if this is the first time anyone's ever
called me, go ahead and instantiate an instance of me, and remember it (in the
\texttt{theInstance} class variable). Then, return the one-and-only instance
of me to the caller, to use to their heart's content.''
\index{lazy instantiation}
This is called \textbf{lazy instantiation}: the only thing that will trigger
the one-and-only \texttt{Configuration} object being instantiated is the first
time anybody calls \texttt{Configuration.instance()}. If nobody ever does call
it, then there won't ever be even one instance of this class created. But
assuming someone does, a new \texttt{Configuration} object will be instantiated
\textit{this time only}. From that point on, all the subsequent times
\texttt{Configuration.instance()} is called, that same object will be returned.
\index{constructor}
\index{private@\texttt{private}}
Then we have the constructor. It can do anything that any constructor can do,
which varies widely depending on what kind of class this is. (For the
\texttt{Configuration} example, perhaps it looks at the filesystem for a
\texttt{.config} file, and if it exists, loads it and remembers all its
contents in instance variables.) The important point to emphasize here is that
\textit{the constructor must be \texttt{private}}). That's because if it
weren't private, any old schmo could just write ``\texttt{new
Configuration()}'' and get a \textit{second} instance of the class, which is
precisely what we want to avoid. Making the constructor \texttt{private} means
nobody is allowed to instantiate a \texttt{Configuration} object...except for
the \texttt{Configuration} class itself, which we saw in the
\texttt{instance()} method.
\section{Using the Singleton}
This pattern allows any other part of the code base to do things like:
\begin{Verbatim}[fontsize=\footnotesize,samepage=true,frame=single]
String bg = Configuration.instance().getParamSetting("bgColor");
\end{Verbatim}
Whenever we call ``\texttt{Configuration.instance()}'' we will get back a\\
\texttt{Configuration} object. (Whether we realize it or not, it's the only
such object that will ever exist.) There's no need to use use the word
\texttt{new}; we just say ``\texttt{Configuration.instance()}'' every time we
need it.
\index{instance variable (inst var)}
Other than this scaffolding, the rest of your Singleton class can do anything
it wants. It will almost certainly have other (non-static) instance variables,
and other methods to carry out its evil deeds. The ``Singleton part'' is just
the \texttt{instance()} and \texttt{theInstance} members, together with the
private constructor.
\index{Factory pattern}
\index{design pattern!Factory}
Singleton is often used in conjunction with the Factory pattern, by the way,
which we will look at in a future chapter.
That's it. Told you it was easy! $\smiley$