-1

Let a virtual pure class Interface and two concrete implementation InterfaceImplA and InterfaceImplB.

I want to have a registry where i can register various implementations of Interface. This registry must be able to create instances of my concrete types, using an arbitrary identifier (QString, std::string..).

A sample application would be like :

  Registry<Interface> registry;
  registry.register<InterfaceImplA>("A");
  registry.register<InterfaceImplB>("B");
  InterfaceImplA* instanceA = registry.create("A");
  InterfaceImplB* instanceB = registry.create("B");

It will be used as as part of a data model serialisation/deserialization component, where the serialized object uses only the interface, but serialized instances may use various implementation.

Arcadien
  • 2,258
  • 16
  • 26

1 Answers1

0
  /*!
   *
   * \brief Allow to implement the Registry pattern applied to interface implementation
   *
   * A registry is needed for each implemented interface. Then, implementation are
   * registered into it, using arbitrary string as identifier. Once registered, the
   * registry is able to provide a concrete instance of a type, given is string identifier.
   *
   */
  template <class InterfaceType, class IdType = std::string>
  class ImplementationRegistry
  {
    typedef boost::function0<InterfaceType *> Creator;
    typedef std::map<IdType, Creator> Creators;
    Creators m_Creators;

  public:
    /*!
     *
     * \brief Register a new concrete type, indexed with given identifier
     *
     * \note the concrete type must be a specialized type of the interface
     *       managed by the registry.
     */
    template <class ConcreteType>
    void Register(const IdType &identifier)
    {
      ConstructorWrapper<ConcreteType> wrapper;
      Creator creator = wrapper;
      m_Creators[identifier] = creator;
    }

    /*!
     *
     * \brief return a concrete implementation og the managed interface according to an identifier
     *
     * \return an implementation or null in the identifier is unknown
     */
    InterfaceType *Create(const IdType &identifier)
    {
      InterfaceType *result = nullptr;
      auto it = m_Creators.find(identifier);
      if (it != m_Creators.end())
      {
        result = it->second();
      }
      return result;
    }

  protected:

    template<class ConcreteType>
    struct ConstructorWrapper
    {
      InterfaceType *operator()() const { return new ConcreteType(); }
    };
  };
}
Arcadien
  • 2,258
  • 16
  • 26