141 |
|
}; |
142 |
|
\end{lstlisting} |
143 |
|
The corresponding implementation is |
144 |
< |
\begin{lstlisting}[float,caption={[A classic Singleton design pattern implementation(II)] Implementation of {\tt IntegratorFactory} class.},label={appendixScheme:singletonImplementation}] |
144 |
> |
\begin{lstlisting}[float,caption={[A classic implementation of Singleton design pattern (II)] Implementation of {\tt IntegratorFactory} class.},label={appendixScheme:singletonImplementation}] |
145 |
|
|
146 |
|
IntegratorFactory::instance_ = NULL; |
147 |
|
|
171 |
|
identifier in the internal map. If it is found, it invokes the |
172 |
|
corresponding creator for the type identifier and returns its |
173 |
|
result. |
174 |
< |
\begin{lstlisting}[float,caption={[].},label={appendixScheme:factoryDeclaration}] |
174 |
> |
\begin{lstlisting}[float,caption={[The implementation of Factory pattern (I)].},label={appendixScheme:factoryDeclaration}] |
175 |
|
class IntegratorCreator; |
176 |
|
class IntegratorFactory { |
177 |
|
public: |
178 |
< |
typedef std::map<std::string, IntegratorCreator*> CreatorMapType; |
178 |
> |
typedef std::map<string, IntegratorCreator*> CreatorMapType; |
179 |
|
|
180 |
|
bool registerIntegrator(IntegratorCreator* creator); |
181 |
|
|
182 |
< |
Integrator* createIntegrator(const std::string& id, SimInfo* info); |
182 |
> |
Integrator* createIntegrator(const string& id, SimInfo* info); |
183 |
|
|
184 |
|
private: |
185 |
|
CreatorMapType creatorMap_; |
186 |
|
}; |
187 |
|
\end{lstlisting} |
188 |
|
|
189 |
< |
\begin{lstlisting}[float,caption={[].},label={appendixScheme:factoryDeclarationImplementation}] |
190 |
< |
bool IntegratorFactory::unregisterIntegrator(const std::string& id) { |
189 |
> |
\begin{lstlisting}[float,caption={[The implementation of Factory pattern (II)].},label={appendixScheme:factoryDeclarationImplementation}] |
190 |
> |
bool IntegratorFactory::unregisterIntegrator(const string& id) { |
191 |
|
return creatorMap_.erase(id) == 1; |
192 |
|
} |
193 |
|
|
194 |
|
Integrator* |
195 |
< |
IntegratorFactory::createIntegrator(const std::string& id, SimInfo* info) { |
195 |
> |
IntegratorFactory::createIntegrator(const string& id, SimInfo* info) { |
196 |
|
CreatorMapType::iterator i = creatorMap_.find(id); |
197 |
|
if (i != creatorMap_.end()) { |
198 |
|
//invoke functor to create object |
203 |
|
} |
204 |
|
\end{lstlisting} |
205 |
|
|
206 |
< |
\begin{lstlisting}[float,caption={[].},label={appendixScheme:integratorCreator}] |
206 |
> |
\begin{lstlisting}[float,caption={[The implementation of Factory pattern (III)].},label={appendixScheme:integratorCreator}] |
207 |
|
|
208 |
|
class IntegratorCreator { |
209 |
|
public: |
210 |
< |
IntegratorCreator(const std::string& ident) : ident_(ident) {} |
210 |
> |
IntegratorCreator(const string& ident) : ident_(ident) {} |
211 |
|
|
212 |
< |
const std::string& getIdent() const { return ident_; } |
212 |
> |
const string& getIdent() const { return ident_; } |
213 |
|
|
214 |
|
virtual Integrator* create(SimInfo* info) const = 0; |
215 |
|
|
216 |
|
private: |
217 |
< |
std::string ident_; |
217 |
> |
string ident_; |
218 |
|
}; |
219 |
|
|
220 |
|
template<class ConcreteIntegrator> |
221 |
|
class IntegratorBuilder : public IntegratorCreator { |
222 |
|
public: |
223 |
< |
IntegratorBuilder(const std::string& ident) : IntegratorCreator(ident) {} |
223 |
> |
IntegratorBuilder(const string& ident) : IntegratorCreator(ident) {} |
224 |
|
virtual Integrator* create(SimInfo* info) const { |
225 |
|
return new ConcreteIntegrator(info); |
226 |
|
} |
230 |
|
\subsection{\label{appendixSection:visitorPattern}Visitor} |
231 |
|
|
232 |
|
The purpose of the Visitor Pattern is to encapsulate an operation |
233 |
< |
that you want to perform on the elements of a data structure. In |
234 |
< |
this way, you can change the operation being performed on a |
235 |
< |
structure without the need of changing the class heirarchy of the |
236 |
< |
elements that you are operating on. |
233 |
> |
that you want to perform on the elements. The operation being |
234 |
> |
performed on a structure can be switched without changing the |
235 |
> |
interfaces of the elements. In other words, one can add virtual |
236 |
> |
functions into a set of classes without modifying their interfaces. |
237 |
> |
The UML class diagram of Visitor patten is shown in |
238 |
> |
Fig.~\ref{appendixFig:visitorUML}. {\tt Dump2XYZ} program in |
239 |
> |
Sec.~\ref{appendixSection:Dump2XYZ} uses Visitor pattern |
240 |
> |
extensively. |
241 |
|
|
242 |
< |
\begin{lstlisting}[float,caption={[].},label={appendixScheme:visitor}] |
242 |
> |
\begin{figure} |
243 |
> |
\centering |
244 |
> |
\includegraphics[width=\linewidth]{architecture.eps} |
245 |
> |
\caption[The architecture of {\sc OOPSE}] {Overview of the structure |
246 |
> |
of {\sc OOPSE}} \label{appendixFig:visitorUML} |
247 |
> |
\end{figure} |
248 |
> |
|
249 |
> |
\begin{lstlisting}[float,caption={[The implementation of Visitor pattern (I)]Source code of the visitor classes.},label={appendixScheme:visitor}] |
250 |
|
class BaseVisitor{ |
251 |
|
public: |
252 |
|
virtual void visit(Atom* atom); |
254 |
|
virtual void visit(RigidBody* rb); |
255 |
|
}; |
256 |
|
\end{lstlisting} |
257 |
< |
\begin{lstlisting}[float,caption={[].},label={appendixScheme:element}] |
257 |
> |
|
258 |
> |
\begin{lstlisting}[float,caption={[The implementation of Visitor pattern (II)]Source code of the element classes.},label={appendixScheme:element}] |
259 |
|
class StuntDouble { |
260 |
|
public: |
261 |
|
virtual void accept(BaseVisitor* v) = 0; |