AbstractFactory.h
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/common/AbstractFactory.h
22 
23  \brief A class that defines the interface of an abstract factory.
24  */
25 
26 #ifndef __TERRALIB_COMMON_INTERNAL_ABSTRACTFACTORY_H
27 #define __TERRALIB_COMMON_INTERNAL_ABSTRACTFACTORY_H
28 
29 // TerraLib
30 #include "FactoryDictionary.h"
31 #include "../core/Exception.h"
32 // Boost
33 #include <boost/noncopyable.hpp>
34 
35 namespace te
36 {
37  namespace common
38  {
39  /*!
40  \class AbstractFactory
41 
42  \brief This class defines the interface of abstract factories without initializing parameters.
43 
44  The abstract factory keeps an internal dictionary (a singleton) to
45  access their concrete factories.
46 
47  A concrete factory is identified by a key of type TFACTORYKEY.
48  TFACTORYKEY must be copy constructible.
49 
50  It will create objects of type TPRODUCT.
51  Note that TPRODUCT is the object type that the factory knows
52  how to create.
53 
54  In order to create an abstract factory, the concrete
55  classes will have to extend the build method.
56  When an object from a concrete factory is created, it is automatically
57  registered in the abstract factory.
58 
59  If you need to initialize the objects created by the factories try to use
60  a derived class from ParameterizedAbstractFactory instead.
61 
62  \ingroup common
63 
64  \sa ParameterizedAbstractFactory, FactoryDictionary
65 
66  \note This class is not thread-safe for multiple writers.
67  */
68  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE = std::less<TFACTORYKEY> >
69  class AbstractFactory : public boost::noncopyable
70  {
71  public:
72 
74 
75  friend class FactoryDictionary<AbstractFactory<TPRODUCT, TFACTORYKEY, TKEYCOMPARE>, TFACTORYKEY, TKEYCOMPARE>;
76 
78 
79  /*!
80  \brief It returns the factory key associated to the concreate factory.
81 
82  \return The factory key associated to the concreate factory.
83  */
84  const TFACTORYKEY& getKey() const;
85 
86  /*!
87  \brief It creates an object with the appropriated factory.
88 
89  \param factoryKey A key that identifies the factory used to build the object.
90 
91  \return It returns a new object created by the given factory.
92 
93  \exception Exception If the concrete factory is not specified or the object can not be built for any reason this methiod may throws an exception.
94 
95  \note The caller of this method will take the ownership of the returned object.
96  */
97  static TPRODUCT* make(const TFACTORYKEY& factoryKey);
98 
99  /*!
100  \brief It returns a reference to the internal dictionary of concrete factories.
101 
102  The dictionary is a singleton.
103 
104  \return A reference to the internal dictionary.
105  */
106  static dictionary_type& getDictionary();
107 
108  static const factory_type* find(const TFACTORYKEY& factoryKey);
109 
110  protected:
111 
112 
113  /*!
114  \brief Concrete factories (derived from this one) must implement this method in order to create objects.
115 
116  \return It returns an object created by the concrete factory.
117  */
118  virtual TPRODUCT* build() = 0;
119 
120  /*!
121  \brief It creates the factory and automatically registers it in the dictionary.
122 
123  \param factoryKey The key that identifies the factory.
124  */
125  AbstractFactory(const TFACTORYKEY& factoryKey);
126 
127  /*!
128  \brief Virtual destructor.
129 
130  \note It will automatically unregister the factory from the dictionary.
131  */
132  virtual ~AbstractFactory();
133 
134  protected:
135 
136  TFACTORYKEY m_factoryKey; //!< The key that identifies the concrete factory: it will be used for unregistering the factory during destruction.
137  };
138 
139  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
141  {
142  return m_factoryKey;
143  }
144 
145  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
146  TPRODUCT* AbstractFactory<TPRODUCT, TFACTORYKEY, TKEYCOMPARE>::make(const TFACTORYKEY& factoryKey)
147  {
148  AbstractFactory<TPRODUCT, TFACTORYKEY, TKEYCOMPARE>* factory = getDictionary().find(factoryKey);
149 
150  if(factory)
151  return factory->build();
152 
153  throw Exception(TE_TR("Concrete factory not found!"));
154  }
155 
156  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
158  {
159  static dictionary_type factoryDictionary; // Internal factory dictionary.
160  return factoryDictionary;
161  }
162 
163  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
165  {
166  const factory_type* factory = getDictionary().find(factoryKey);
167 
168  return factory;
169  }
170 
171  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
173  : m_factoryKey(factoryKey)
174  {
175  getDictionary().insert(factoryKey, this);
176  }
177 
178  template<class TPRODUCT, class TFACTORYKEY, class TKEYCOMPARE> inline
180  {
181  getDictionary().remove(m_factoryKey);
182  }
183 
184  } // end namespace common
185 } // end namespace te
186 
187 #endif // __TERRALIB_COMMON_INTERNAL_ABSTRACTFACTORY_H
188 
This class defines the interface of abstract factories without initializing parameters.
FactoryDictionary< AbstractFactory< TPRODUCT, TFACTORYKEY, TKEYCOMPARE >, TFACTORYKEY, TKEYCOMPARE > dictionary_type
virtual ~AbstractFactory()
Virtual destructor.
void insert(const TFACTORYKEY &factoryKey, TFACTORY *factory)
It inserts a pointer to a factory and makes it associated to the factory key.
static dictionary_type & getDictionary()
It returns a reference to the internal dictionary of concrete factories.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:243
A dictionary for a Factory.
URI C++ Library.
AbstractFactory(const TFACTORYKEY &factoryKey)
It creates the factory and automatically registers it in the dictionary.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
static TPRODUCT * make(const TFACTORYKEY &factoryKey)
It creates an object with the appropriated factory.
const TFACTORYKEY & getKey() const
It returns the factory key associated to the concreate factory.
static const factory_type * find(const TFACTORYKEY &factoryKey)
TFACTORYKEY m_factoryKey
The key that identifies the concrete factory: it will be used for unregistering the factory during de...
virtual TPRODUCT * build()=0
Concrete factories (derived from this one) must implement this method in order to create objects...
This class represents a dictionary of factories.