Last active
December 15, 2015 07:29
-
-
Save felixgirault/5223712 to your computer and use it in GitHub Desktop.
A generic factory to be used in Qt applications.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef FACTORY_H | |
#define FACTORY_H | |
#include <QList> | |
#include <QHash> | |
typedef QHash< QString, QString > Informations; | |
typedef QHashIterator< QString, QString > InformationsIterator; | |
/** | |
* A generic factory. | |
*/ | |
template< class Product > | |
class Factory { | |
Q_DISABLE_COPY( Factory ) | |
public: | |
typedef Product* ( *CreateFunction )( ); | |
private: | |
class ProductMetaType { | |
public: | |
/** | |
* Default constructor. | |
*/ | |
ProductMetaType( ) { } | |
/** | |
* Constructor. | |
* | |
* @param name Name of the product. | |
* @param description Description of the product. | |
* @param function Helper function to create the product. | |
*/ | |
ProductMetaType( | |
const QString& name, | |
const QString& description, | |
CreateFunction function | |
) : | |
_name( name ), | |
_description( description ), | |
_create( function ) | |
{ } | |
/** | |
* Returns the name of the product. | |
* | |
* @return Product name. | |
*/ | |
QString name( ) const{ | |
return _name; | |
} | |
/** | |
* Returns the description of the product. | |
* | |
* @return Product description. | |
*/ | |
QString description( ) const { | |
return _description; | |
} | |
/** | |
* Returns an instance of a product. | |
* | |
* @return Product instance. | |
*/ | |
Product* create( ) const { | |
return _create( ); | |
} | |
private: | |
QString _name; //!< Name of the product. | |
QString _description; //!< Description of the product. | |
CreateFunction _create; //!< Helper function which creates a product. | |
}; | |
public: | |
/** | |
* Registers a new product. | |
* | |
* @param name Name of the product. | |
* @param description Description of the product. | |
* @param function Helper function to create the product. | |
*/ | |
static void registerProductMetaType( | |
const QString& name, | |
const QString& description, | |
CreateFunction function | |
) { | |
Factory& _this = instance( ); | |
_this._registry.append( ProductMetaType( name, description, function )); | |
} | |
/** | |
* Returns a set of informations about all the registered types, in | |
* the form < name, description >. | |
* | |
* @return Map of informations. | |
*/ | |
static Informations informations( ) { | |
Factory& _this = instance( ); | |
Informations informations; | |
foreach ( ProductMetaType meta, _this._registry ) { | |
informations.insert( meta.name( ), meta.description( )); | |
} | |
return informations; | |
} | |
/** | |
* Creates the product which is associated with the given name. | |
* | |
* @param name Name of the product. | |
* @return An instance of the product, or 0 if there is no product | |
* found with the given name. | |
*/ | |
static Product* create( const QString& name ) { | |
Factory& _this = instance( ); | |
foreach ( const ProductMetaType& meta, _this._registry ) { | |
if ( name.compare( meta.name( )) == 0 ) { | |
return meta.create( ); | |
} | |
} | |
return 0; | |
} | |
private: | |
/** | |
* Private constructor to prevent copy. | |
*/ | |
Factory( ) { } | |
/** | |
* Returns a unique instance of the Factory. | |
* | |
* @return Unique instance. | |
*/ | |
static Factory& instance( ) { | |
static Factory factory; | |
return factory; | |
} | |
private: | |
QList< ProductMetaType > _registry; //!< Regitry of products meta. | |
}; | |
/** | |
* An utility class to register products for the factory. | |
*/ | |
template< class Ancestor, class Product > | |
class ProductRegistrar { | |
public: | |
/** | |
* Constructor. | |
* | |
* @param name Name of the product. | |
* @param description Description of the product. | |
*/ | |
ProductRegistrar( const QString& name, const QString& description ) { | |
Factory< Ancestor >::registerProductMetaType( name, description, create ); | |
} | |
/** | |
* Returns an instance of the product. | |
* | |
* @return Product instance. | |
*/ | |
static Ancestor* create( ) { | |
return new Product; | |
} | |
}; | |
/** | |
* A macro to register products easily. | |
*/ | |
#define REGISTER_PRODUCT( baseClassName, className, name, description ) \ | |
ProductRegistrar< baseClassName, className > className##Product( \ | |
QObject::tr( name ), \ | |
QObject::tr( description ) \ | |
); | |
#endif // FACTORY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Registering a class. | |
*/ | |
REGISTER_PRODUCT( | |
Database, // Base class | |
MySqlDatabase, // Registered class | |
"MySql", // Name | |
"A MySql database." // Description | |
) | |
/** | |
* Getting informations about registered classes. | |
*/ | |
Informations infos = Factory< Database >::informations( ); | |
// infos contains [ "MySql" => "A MySql database" ]. | |
/** | |
* Instanciating an object. | |
*/ | |
Database* db = Factory< Database >::create( "MySql" ); | |
// db is an instance of MySqlDatabase. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment