Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

How to implement "Registry pattern" in C++, using single registry for many interface implementation

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  /*!
   *
   * rief 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:
    /*!
     *
     * rief Register a new concrete type, indexed with given identifier
     *
     * 
ote 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;
    }

    /*!
     *
     * rief return a concrete implementation og the managed interface according to an identifier
     *
     * 
eturn 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(); }
    };
  };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...