ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/tengDissertation/Appendix.tex
(Generate patch)

Comparing trunk/tengDissertation/Appendix.tex (file contents):
Revision 2821 by tim, Thu Jun 8 06:39:37 2006 UTC vs.
Revision 2835 by tim, Thu Jun 8 22:39:54 2006 UTC

# Line 129 | Line 129 | is declared as
129   designs, such as lifespan control \textit{etc}, we only use the
130   static data approach in {\sc OOPSE}. {\tt IntegratorFactory} class
131   is declared as
132 < \begin{lstlisting}[float,caption={[A classic Singleton design pattern implementation(I)] Declaration of {\tt IntegratorFactory} class.},label={appendixScheme:singletonDeclaration}]
132 > \begin{lstlisting}[float,caption={[A classic Singleton design pattern implementation(I)] The declaration of of simple Singleton pattern.},label={appendixScheme:singletonDeclaration}]
133  
134 <  class IntegratorFactory {
135 <    public:
136 <      static IntegratorFactory* getInstance();
137 <    protected:
138 <      IntegratorFactory();
139 <    private:
140 <      static IntegratorFactory* instance_;
141 <  };
134 > class IntegratorFactory {
135 > public:
136 >  static IntegratorFactory*
137 >  getInstance();
138 > protected:
139 >  IntegratorFactory();
140 > private:
141 >  static IntegratorFactory* instance_;
142 > };
143 >
144   \end{lstlisting}
145   The corresponding implementation is
146 < \begin{lstlisting}[float,caption={[A classic Singleton design pattern implementation(II)] Implementation of {\tt IntegratorFactory} class.},label={appendixScheme:singletonImplementation}]
146 > \begin{lstlisting}[float,caption={[A classic implementation of Singleton design pattern (II)] The implementation of simple Singleton pattern.},label={appendixScheme:singletonImplementation}]
147  
148   IntegratorFactory::instance_ = NULL;
149  
# Line 151 | Line 153 | IntegratorFactory* getInstance() {
153    }
154    return instance_;
155   }
156 +
157   \end{lstlisting}
158   Since constructor is declared as {\tt protected}, a client can not
159   instantiate {\tt IntegratorFactory} directly. Moreover, since the
# Line 166 | Line 169 | implemented by delegating the creation operation to th
169   with the problem of creating objects without specifying the exact
170   class of object that will be created. Factory Method is typically
171   implemented by delegating the creation operation to the subclasses.
172 < \begin{lstlisting}[float,caption={[].},label={appendixScheme:factoryDeclaration}]
173 <  class IntegratorCreator;
174 <  class IntegratorFactory {
175 <    public:
176 <      typedef std::map<std::string, IntegratorCreator*> CreatorMapType;
172 > {\tt Integrator} class Parameterized Factory pattern where factory
173 > method ({\tt createIntegrator} member function) creates products
174 > based on the identifier (see
175 > List.~\ref{appendixScheme:factoryDeclaration}). If the identifier
176 > has been already registered, the factory method will invoke the
177 > corresponding creator (see List.~\ref{integratorCreator}) which
178 > utilizes the modern C++ template technique to avoid subclassing.
179 > \begin{lstlisting}[float,caption={[The implementation of Parameterized Factory pattern (I)]Source code of {\tt IntegratorFactory} class.},label={appendixScheme:factoryDeclaration}]
180  
181 <      /**
182 <       * Registers a creator with a type identifier
183 <       * @return true if registration is successful, otherwise return false
178 <       * @id the identification of the concrete object
179 <       * @creator the object responsible to create the concrete object
180 <       */
181 <      bool registerIntegrator(IntegratorCreator* creator);
181 > class IntegratorFactory {
182 > public:
183 >  typedef std::map<string, IntegratorCreator*> CreatorMapType;
184  
185 <      /**
186 <       * Looks up the type identifier in the internal map. If it is found, it invokes the
185 <       * corresponding creator for the type identifier and returns its result.
186 <       * @return a pointer of the concrete object, return NULL if no creator is registed for
187 <       * creating this concrete object
188 <       * @param id the identification of the concrete object
189 <       */
190 <      Integrator* createIntegrator(const std::string& id, SimInfo* info);
191 <
192 <    private:
193 <      CreatorMapType creatorMap_;
194 <  };
195 < \end{lstlisting}
196 <
197 < \begin{lstlisting}[float,caption={[].},label={appendixScheme:factoryDeclarationImplementation}]
198 <  bool IntegratorFactory::unregisterIntegrator(const std::string& id) {
199 <    return creatorMap_.erase(id) == 1;
185 >  bool registerIntegrator(IntegratorCreator* creator) {
186 >    return creatorMap_.insert(creator->getIdent(), creator).second;
187    }
188  
189 <  Integrator* IntegratorFactory::createIntegrator(const std::string& id, SimInfo* info) {
189 >  Integrator* createIntegrator(const string& id, SimInfo* info) {
190 >    Integrator* result = NULL;
191      CreatorMapType::iterator i = creatorMap_.find(id);
192      if (i != creatorMap_.end()) {
193 <      //invoke functor to create object
206 <      return (i->second)->create(info);
207 <    } else {
208 <      return NULL;
193 >      result = (i->second)->create(info);
194      }
195 +    return result;
196    }
197 +
198 + private:
199 +  CreatorMapType creatorMap_;
200 + };
201   \end{lstlisting}
202 + \begin{lstlisting}[float,caption={[The implementation of Parameterized Factory pattern (III)]Source code of creator classes.},label={appendixScheme:integratorCreator}]
203  
204 < \begin{lstlisting}[float,caption={[].},label={appendixScheme:integratorCreator}]
204 > class IntegratorCreator {
205 > public:
206 >    IntegratorCreator(const string& ident) : ident_(ident) {}
207  
208 <  class IntegratorCreator {
216 <  public:
217 <    IntegratorCreator(const std::string& ident) : ident_(ident) {}
218 <    virtual ~IntegratorCreator() {}
219 <    const std::string& getIdent() const { return ident_; }
208 >    const string& getIdent() const { return ident_; }
209  
210      virtual Integrator* create(SimInfo* info) const = 0;
211  
212 <  private:
213 <    std::string ident_;
214 <  };
212 > private:
213 >    string ident_;
214 > };
215  
216 <  template<class ConcreteIntegrator>
217 <  class IntegratorBuilder : public IntegratorCreator {
218 <  public:
219 <    IntegratorBuilder(const std::string& ident) : IntegratorCreator(ident) {}
220 <    virtual  Integrator* create(SimInfo* info) const {return new ConcreteIntegrator(info);}
221 <  };
216 > template<class ConcreteIntegrator>
217 > class IntegratorBuilder : public IntegratorCreator {
218 > public:
219 >  IntegratorBuilder(const string& ident)
220 >                   : IntegratorCreator(ident) {}
221 >  virtual  Integrator* create(SimInfo* info) const {
222 >    return new ConcreteIntegrator(info);
223 >  }
224 > };
225   \end{lstlisting}
226  
227   \subsection{\label{appendixSection:visitorPattern}Visitor}
228  
229   The purpose of the Visitor Pattern is to encapsulate an operation
230 < that you want to perform on the elements of a data structure. In
231 < this way, you can change the operation being performed on a
232 < structure without the need of changing the class heirarchy of the
233 < elements that you are operating on.
230 > that you want to perform on the elements. The operation being
231 > performed on a structure can be switched without changing the
232 > interfaces of the elements. In other words, one can add virtual
233 > functions into a set of classes without modifying their interfaces.
234 > Fig.~\ref{appendixFig:visitorUML} demonstrates the structure of
235 > Visitor pattern which is used extensively in {\tt Dump2XYZ}. In
236 > order to convert an OOPSE dump file, a series of distinct and
237 > unrelated operations are performed on different StuntDoubles.
238 > Visitor allows one to keep related operations together by packing
239 > them into one class. {\tt BaseAtomVisitor} is a typical example of
240 > visitor in {\tt Dump2XYZ} program{see
241 > List.~\ref{appendixScheme:visitor}}. In contrast to the operations,
242 > the object structure or element classes rarely change(See
243 > Fig.~\ref{oopseFig:heirarchy} and
244 > List.~\ref{appendixScheme:element}).
245  
246 < \begin{lstlisting}[float,caption={[].},label={appendixScheme:visitor}]
247 <  class BaseVisitor{
248 <    public:
249 <      virtual void visit(Atom* atom);
250 <      virtual void visit(DirectionalAtom* datom);
251 <      virtual void visit(RigidBody* rb);
252 <  };
246 >
247 > \begin{figure}
248 > \centering
249 > \includegraphics[width=\linewidth]{visitor.eps}
250 > \caption[The UML class diagram of Visitor patten] {The UML class
251 > diagram of Visitor patten.} \label{appendixFig:visitorUML}
252 > \end{figure}
253 >
254 > \begin{lstlisting}[float,caption={[The implementation of Visitor pattern (I)]Source code of the visitor classes.},label={appendixScheme:visitor}]
255 >
256 > class BaseVisitor{
257 > public:
258 >  virtual void visit(Atom* atom);
259 >  virtual void visit(DirectionalAtom* datom);
260 >  virtual void visit(RigidBody* rb);
261 > };
262 >
263 > class BaseAtomVisitor:public BaseVisitor{ public:
264 >  virtual void visit(Atom* atom);
265 >  virtual void visit(DirectionalAtom* datom);
266 >  virtual void visit(RigidBody* rb);
267 > };
268 >
269   \end{lstlisting}
251 \begin{lstlisting}[float,caption={[].},label={appendixScheme:element}]
252  class StuntDouble {
253    public:
254      virtual void accept(BaseVisitor* v) = 0;
255  };
270  
271 <  class Atom: public StuntDouble {
258 <    public:
259 <      virtual void accept{BaseVisitor* v*} {v->visit(this);}
260 <  };
271 > \begin{lstlisting}[float,caption={[The implementation of Visitor pattern (II)]Source code of the element classes.},label={appendixScheme:element}]
272  
273 <  class DirectionalAtom: public Atom {
274 <    public:
275 <      virtual void accept{BaseVisitor* v*} {v->visit(this);}
276 <  };
273 > class StuntDouble {
274 > public:
275 >  virtual void accept(BaseVisitor* v) = 0;
276 > };
277  
278 <  class RigidBody: public StuntDouble {
279 <    public:
280 <      virtual void accept{BaseVisitor* v*} {v->visit(this);}
281 <  };
278 > class Atom: public StuntDouble {
279 > public:
280 >  virtual void accept{BaseVisitor* v*} {
281 >    v->visit(this);
282 >  }
283 > };
284  
285 + class DirectionalAtom: public Atom {
286 + public:
287 +  virtual void accept{BaseVisitor* v*} {
288 +    v->visit(this);
289 +  }
290 + };
291 +
292 + class RigidBody: public StuntDouble {
293 + public:
294 +  virtual void accept{BaseVisitor* v*} {
295 +    v->visit(this);
296 +  }
297 + };
298 +
299   \end{lstlisting}
300 +
301   \section{\label{appendixSection:concepts}Concepts}
302  
303   OOPSE manipulates both traditional atoms as well as some objects
304   that {\it behave like atoms}.  These objects can be rigid
305   collections of atoms or atoms which have orientational degrees of
306 < freedom.  Here is a diagram of the class heirarchy:
307 <
306 > freedom.  A diagram of the class heirarchy is illustrated in
307 > Fig.~\ref{oopseFig:heirarchy}. Every Molecule, Atom and
308 > DirectionalAtom in {\sc OOPSE} have their own names which are
309 > specified in the {\tt .md} file. In contrast, RigidBodies are
310 > denoted by their membership and index inside a particular molecule:
311 > [MoleculeName]\_RB\_[index] (the contents inside the brackets depend
312 > on the specifics of the simulation). The names of rigid bodies are
313 > generated automatically. For example, the name of the first rigid
314 > body in a DMPC molecule is DMPC\_RB\_0.
315   %\begin{figure}
316   %\centering
317 < %\includegraphics[width=3in]{heirarchy.eps}
318 < %\caption[Class heirarchy for StuntDoubles in {\sc oopse}-3.0]{ \\
319 < %The class heirarchy of StuntDoubles in {\sc oopse}-3.0. The
320 < %selection syntax allows the user to select any of the objects that
321 < %are descended from a StuntDouble.} \label{oopseFig:heirarchy}
317 > %\includegraphics[width=\linewidth]{heirarchy.eps}
318 > %\caption[Class heirarchy for ojects in {\sc OOPSE}]{ A diagram of
319 > %the class heirarchy.
320 > %\begin{itemize}
321 > %\item A {\bf StuntDouble} is {\it any} object that can be manipulated by the
322 > %integrators and minimizers.
323 > %\item An {\bf Atom} is a fundamental point-particle that can be moved around during a simulation.
324 > %\item A {\bf DirectionalAtom} is an atom which has {\it orientational} as well as translational degrees of freedom.
325 > %\item A {\bf RigidBody} is a collection of {\bf Atom}s or {\bf
326 > %DirectionalAtom}s which behaves as a single unit.
327 > %\end{itemize}
328 > %} \label{oopseFig:heirarchy}
329   %\end{figure}
330  
289 \begin{itemize}
290 \item A {\bf StuntDouble} is {\it any} object that can be manipulated by the
291 integrators and minimizers.
292 \item An {\bf Atom} is a fundamental point-particle that can be moved around during a simulation.
293 \item A {\bf DirectionalAtom} is an atom which has {\it orientational} as well as translational degrees of freedom.
294 \item A {\bf RigidBody} is a collection of {\bf Atom}s or {\bf
295 DirectionalAtom}s which behaves as a single unit.
296 \end{itemize}
297
298 Every Molecule, Atom and DirectionalAtom in {\sc OOPSE} have their
299 own names which are specified in the {\tt .md} file. In contrast,
300 RigidBodies are denoted by their membership and index inside a
301 particular molecule: [MoleculeName]\_RB\_[index] (the contents
302 inside the brackets depend on the specifics of the simulation). The
303 names of rigid bodies are generated automatically. For example, the
304 name of the first rigid body in a DMPC molecule is DMPC\_RB\_0.
305
331   \section{\label{appendixSection:syntax}Syntax of the Select Command}
332  
333   The most general form of the select command is: {\tt select {\it

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines