--- trunk/tengDissertation/Appendix.tex 2006/06/08 22:39:54 2835 +++ trunk/tengDissertation/Appendix.tex 2006/06/09 02:20:39 2837 @@ -118,6 +118,7 @@ The Singleton pattern not only provides a mechanism to OOPSE}. \subsection{\label{appendixSection:singleton}Singleton} + The Singleton pattern not only provides a mechanism to restrict instantiation of a class to one object, but also provides a global point of access to the object. Currently implemented as a global @@ -127,8 +128,9 @@ static data approach in {\sc OOPSE}. {\tt IntegratorFa pollution.Although the singleton pattern can be implemented in various ways to account for different aspects of the software designs, such as lifespan control \textit{etc}, we only use the -static data approach in {\sc OOPSE}. {\tt IntegratorFactory} class -is declared as +static data approach in {\sc OOPSE}. IntegratorFactory class is +declared as + \begin{lstlisting}[float,caption={[A classic Singleton design pattern implementation(I)] The declaration of of simple Singleton pattern.},label={appendixScheme:singletonDeclaration}] class IntegratorFactory { @@ -142,7 +144,9 @@ The corresponding implementation is }; \end{lstlisting} + The corresponding implementation is + \begin{lstlisting}[float,caption={[A classic implementation of Singleton design pattern (II)] The implementation of simple Singleton pattern.},label={appendixScheme:singletonImplementation}] IntegratorFactory::instance_ = NULL; @@ -155,29 +159,31 @@ Since constructor is declared as {\tt protected}, a cl } \end{lstlisting} -Since constructor is declared as {\tt protected}, a client can not -instantiate {\tt IntegratorFactory} directly. Moreover, since the -member function {\tt getInstance} serves as the only entry of access -to {\tt IntegratorFactory}, this approach fulfills the basic -requirement, a single instance. Another consequence of this approach -is the automatic destruction since static data are destroyed upon -program termination. +Since constructor is declared as protected, a client can not +instantiate IntegratorFactory directly. Moreover, since the member +function getInstance serves as the only entry of access to +IntegratorFactory, this approach fulfills the basic requirement, a +single instance. Another consequence of this approach is the +automatic destruction since static data are destroyed upon program +termination. + \subsection{\label{appendixSection:factoryMethod}Factory Method} Categoried as a creational pattern, the Factory Method pattern deals with the problem of creating objects without specifying the exact class of object that will be created. Factory Method is typically implemented by delegating the creation operation to the subclasses. -{\tt Integrator} class Parameterized Factory pattern where factory -method ({\tt createIntegrator} member function) creates products -based on the identifier (see -List.~\ref{appendixScheme:factoryDeclaration}). If the identifier -has been already registered, the factory method will invoke the -corresponding creator (see List.~\ref{integratorCreator}) which -utilizes the modern C++ template technique to avoid subclassing. -\begin{lstlisting}[float,caption={[The implementation of Parameterized Factory pattern (I)]Source code of {\tt IntegratorFactory} class.},label={appendixScheme:factoryDeclaration}] +Parameterized Factory pattern where factory method ( +createIntegrator member function) creates products based on the +identifier (see List.~\ref{appendixScheme:factoryDeclaration}). If +the identifier has been already registered, the factory method will +invoke the corresponding creator (see List.~\ref{integratorCreator}) +which utilizes the modern C++ template technique to avoid excess +subclassing. +\begin{lstlisting}[float,caption={[The implementation of Parameterized Factory pattern (I)]Source code of IntegratorFactory class.},label={appendixScheme:factoryDeclaration}] + class IntegratorFactory { public: typedef std::map CreatorMapType; @@ -199,6 +205,7 @@ class IntegratorFactory { (private) CreatorMapType creatorMap_; }; \end{lstlisting} + \begin{lstlisting}[float,caption={[The implementation of Parameterized Factory pattern (III)]Source code of creator classes.},label={appendixScheme:integratorCreator}] class IntegratorCreator { @@ -226,24 +233,22 @@ The purpose of the Visitor Pattern is to encapsulate a \subsection{\label{appendixSection:visitorPattern}Visitor} -The purpose of the Visitor Pattern is to encapsulate an operation -that you want to perform on the elements. The operation being -performed on a structure can be switched without changing the -interfaces of the elements. In other words, one can add virtual -functions into a set of classes without modifying their interfaces. -Fig.~\ref{appendixFig:visitorUML} demonstrates the structure of -Visitor pattern which is used extensively in {\tt Dump2XYZ}. In -order to convert an OOPSE dump file, a series of distinct and -unrelated operations are performed on different StuntDoubles. -Visitor allows one to keep related operations together by packing -them into one class. {\tt BaseAtomVisitor} is a typical example of -visitor in {\tt Dump2XYZ} program{see -List.~\ref{appendixScheme:visitor}}. In contrast to the operations, -the object structure or element classes rarely change(See -Fig.~\ref{oopseFig:heirarchy} and -List.~\ref{appendixScheme:element}). +The visitor pattern is designed to decouple the data structure and +algorithms used upon them by collecting related operation from +element classes into other visitor classes, which is equivalent to +adding virtual functions into a set of classes without modifying +their interfaces. Fig.~\ref{appendixFig:visitorUML} demonstrates the +structure of Visitor pattern which is used extensively in {\tt +Dump2XYZ}. In order to convert an OOPSE dump file, a series of +distinct operations are performed on different StuntDoubles (See the +class hierarchy in Fig.~\ref{oopseFig:hierarchy} and the declaration +in List.~\ref{appendixScheme:element}). Since the hierarchies +remains stable, it is easy to define a visit operation (see +List.~\ref{appendixScheme:visitor}) for each class of StuntDouble. +Note that using Composite pattern\cite{Gamma1994}, CompositVisitor +manages a priority visitor list and handles the execution of every +visitor in the priority list on different StuntDoubles. - \begin{figure} \centering \includegraphics[width=\linewidth]{visitor.eps} @@ -251,46 +256,41 @@ diagram of Visitor patten.} \label{appendixFig:visitor diagram of Visitor patten.} \label{appendixFig:visitorUML} \end{figure} -\begin{lstlisting}[float,caption={[The implementation of Visitor pattern (I)]Source code of the visitor classes.},label={appendixScheme:visitor}] +%\begin{figure} +%\centering +%\includegraphics[width=\linewidth]{hierarchy.eps} +%\caption[Class hierarchy for ojects in {\sc OOPSE}]{ A diagram of +%the class hierarchy. +%\begin{itemize} +%\item A {\bf StuntDouble} is {\it any} object that can be manipulated by the +%integrators and minimizers. +%\item An {\bf Atom} is a fundamental point-particle that can be moved around during a simulation. +%\item A {\bf DirectionalAtom} is an atom which has {\it orientational} as well as translational degrees of freedom. +%\item A {\bf RigidBody} is a collection of {\bf Atom}s or {\bf +%DirectionalAtom}s which behaves as a single unit. +%\end{itemize} +%} \label{oopseFig:hierarchy} +%\end{figure} -class BaseVisitor{ -public: - virtual void visit(Atom* atom); - virtual void visit(DirectionalAtom* datom); - virtual void visit(RigidBody* rb); -}; - -class BaseAtomVisitor:public BaseVisitor{ public: - virtual void visit(Atom* atom); - virtual void visit(DirectionalAtom* datom); - virtual void visit(RigidBody* rb); -}; - -\end{lstlisting} - \begin{lstlisting}[float,caption={[The implementation of Visitor pattern (II)]Source code of the element classes.},label={appendixScheme:element}] -class StuntDouble { -public: +class StuntDouble { public: virtual void accept(BaseVisitor* v) = 0; }; -class Atom: public StuntDouble { -public: +class Atom: public StuntDouble { public: virtual void accept{BaseVisitor* v*} { v->visit(this); } }; -class DirectionalAtom: public Atom { -public: +class DirectionalAtom: public Atom { public: virtual void accept{BaseVisitor* v*} { v->visit(this); } }; -class RigidBody: public StuntDouble { -public: +class RigidBody: public StuntDouble { public: virtual void accept{BaseVisitor* v*} { v->visit(this); } @@ -298,13 +298,75 @@ class RigidBody: public StuntDouble { (public) \end{lstlisting} +\begin{lstlisting}[float,caption={[The implementation of Visitor pattern (I)]Source code of the visitor classes.},label={appendixScheme:visitor}] + +class BaseVisitor{ +public: + virtual void visit(Atom* atom); + virtual void visit(DirectionalAtom* datom); + virtual void visit(RigidBody* rb); +}; + +class BaseAtomVisitor:public BaseVisitor{ public: + virtual void visit(Atom* atom); + virtual void visit(DirectionalAtom* datom); + virtual void visit(RigidBody* rb); +}; + +class SSDAtomVisitor:public BaseAtomVisitor{ public: + virtual void visit(Atom* atom); + virtual void visit(DirectionalAtom* datom); + virtual void visit(RigidBody* rb); +}; + +class CompositeVisitor: public BaseVisitor { +public: + + typedef list > VistorListType; + typedef VistorListType::iterator VisitorListIterator; + virtual void visit(Atom* atom) { + VisitorListIterator i; + BaseVisitor* curVisitor; + for(i = visitorList.begin();i != visitorList.end();++i) { + atom->accept(*i); + } + } + + virtual void visit(DirectionalAtom* datom) { + VisitorListIterator i; + BaseVisitor* curVisitor; + for(i = visitorList.begin();i != visitorList.end();++i) { + atom->accept(*i); + } + } + + virtual void visit(RigidBody* rb) { + VisitorListIterator i; + std::vector myAtoms; + std::vector::iterator ai; + myAtoms = rb->getAtoms(); + for(i = visitorList.begin();i != visitorList.end();++i) {{ + rb->accept(*i); + for(ai = myAtoms.begin(); ai != myAtoms.end(); ++ai){ + (*ai)->accept(*i); + } + } + + void addVisitor(BaseVisitor* v, int priority); + + protected: + VistorListType visitorList; +}; + +\end{lstlisting} + \section{\label{appendixSection:concepts}Concepts} OOPSE manipulates both traditional atoms as well as some objects that {\it behave like atoms}. These objects can be rigid collections of atoms or atoms which have orientational degrees of -freedom. A diagram of the class heirarchy is illustrated in -Fig.~\ref{oopseFig:heirarchy}. Every Molecule, Atom and +freedom. A diagram of the class hierarchy is illustrated in +Fig.~\ref{oopseFig:hierarchy}. Every Molecule, Atom and DirectionalAtom in {\sc OOPSE} have their own names which are specified in the {\tt .md} file. In contrast, RigidBodies are denoted by their membership and index inside a particular molecule: @@ -312,32 +374,20 @@ body in a DMPC molecule is DMPC\_RB\_0. on the specifics of the simulation). The names of rigid bodies are generated automatically. For example, the name of the first rigid body in a DMPC molecule is DMPC\_RB\_0. -%\begin{figure} -%\centering -%\includegraphics[width=\linewidth]{heirarchy.eps} -%\caption[Class heirarchy for ojects in {\sc OOPSE}]{ A diagram of -%the class heirarchy. -%\begin{itemize} -%\item A {\bf StuntDouble} is {\it any} object that can be manipulated by the -%integrators and minimizers. -%\item An {\bf Atom} is a fundamental point-particle that can be moved around during a simulation. -%\item A {\bf DirectionalAtom} is an atom which has {\it orientational} as well as translational degrees of freedom. -%\item A {\bf RigidBody} is a collection of {\bf Atom}s or {\bf -%DirectionalAtom}s which behaves as a single unit. -%\end{itemize} -%} \label{oopseFig:heirarchy} -%\end{figure} \section{\label{appendixSection:syntax}Syntax of the Select Command} -The most general form of the select command is: {\tt select {\it -expression}}. This expression represents an arbitrary set of -StuntDoubles (Atoms or RigidBodies) in {\sc OOPSE}. Expressions are -composed of either name expressions, index expressions, predefined -sets, user-defined expressions, comparison operators, within -expressions, or logical combinations of the above expression types. -Expressions can be combined using parentheses and the Boolean -operators. +{\sc OOPSE} provides a powerful selection utility to select +StuntDoubles. The most general form of the select command is: + +{\tt select {\it expression}}. + +This expression represents an arbitrary set of StuntDoubles (Atoms +or RigidBodies) in {\sc OOPSE}. Expressions are composed of either +name expressions, index expressions, predefined sets, user-defined +expressions, comparison operators, within expressions, or logical +combinations of the above expression types. Expressions can be +combined using parentheses and the Boolean operators. \subsection{\label{appendixSection:logical}Logical expressions}