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 2831 by tim, Thu Jun 8 21:02:53 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines