Prototype 模式示例代码 (C++)

在某公司使用的框架源代码里看到了 Prototype 模式, 这里把代码提炼总结一下:

// --------------------------------------------------------------------------------------
/** Abstract.h **/

class Abstract { // prototype manager
private:
    typedef map<type_t, Abstract*> RegMap;
    static RegMap& getRegistry() { 
        static RegMap registry; // initialized at the first time the function is called  
        return registry;
    }
public:
    Abstract(const type_t& type) {
        if (lookup(type) != NULL)
            getRegistry.insert(type, this);
    }

    virtual ~Abstract() { }

    virtual Abstract* clone() = 0;  

    static Abstract* create(const type_t& type) { 
        Abstract* stub = lookup(type);
        return stub != NULL : stub->clone() : NULL; 
    }

    virtual void destroy() { delete this; }

    static const Abstract* lookup(const type_t& type) {
        if (getRegistry().find(type) != getRegistry().end())
            return getRegistry()[type];
        return NULL;
    }
};

// --------------------------------------------------------------------------------------
/** ConcreteA.h **/

class ConcreteA : public Abstract {
    // ... data members
    ConcreteA* clone() { return new ConcreteA(*this); }
public:
    ConcreteA() : Abstract(CONC_TYPE_A) { } // CONC_TYPE_A : constant
    // ... other members
};

// --------------------------------------------------------------------------------------
/** ConcreteA.cpp **/

    static ConcreteA __concrete_a_stub/*(...)*/; // static initialized

// --------------------------------------------------------------------------------------
/** ConcreteB.h **/

class ConcreteB : public Abstract {
    // ... data members
    ConcreteB* clone() { return new ConcreteB(*this); }
public:
    ConcreteB() : Abstract(CONC_TYPE_B) { } // CONC_TYPE_B : constant
    // ... other members
};

// --------------------------------------------------------------------------------------
/** ConcreteB.cpp **/

    static ConcreteB __concrete_b_stub/*(...)*/; 

// --------------------------------------------------------------------------------------
/** Client **/

Abstract* p_abstract = Abstract::create(CONC_TYPE_A /* or CONC_TYPE_B */);
// ... some code
p_abstract->destroy();

// --------------------------------------------------------------------------------------

使用 Prototype 模式的好处 :
1. 对客户端隐藏具体的产品类 (product classes), 这样就能够减少客户端可见的名字数目,降低系统的复杂性;
2. 可以动态的添加或者删除产品类的原型;
3. 相对于工厂方法模式,简化了继承体系结构。
4. 可以动态配置一个应用所能使用的类。在上面代码中, 所有的原型是在 main 函数执行之前注册到 prototype manager 持有的注册表中的(静态初始化过程)。 实际上, 注册表项的加载可以推迟到 main 函数执行后, 即动态地加载到注册表中。

原文地址:https://www.cnblogs.com/william-cheung/p/4767657.html