原型模式

2014-11-23 22:57:53 · 作者: · 浏览: 2
原型模式,如其名称,核心就是要实现一个原型类,该类支持clone操作,从而客户可以从原型克隆出具体的类。
其效果主要有如下:
可以动态增加和删除产品。这个就是通过clone代替new等操作,也避免了客户与具体类打交道。
通过改变对象的值,指定新的对象。clone出一个新对象后可以修改其参数改变对象,如果参数较多,可以提供类似initialize方法。
减少creator类,减少子类数目。客户看起来直接从一个原型克隆出一个新的对象,而不是跟工厂方法打交道,因而少了一个类层次。
动态配置应用,这个真是没想明白。也没个例子,我想大致意思就是将原型编译成动态库等,初始化阶段构造原型对象,运行时从原型克隆出新的类吧。
写了个简单demo,供参考:
/** 
 * @file test_prototype.cpp 
 * @author itegel 
 * @date 2013/09/18 15:15:26 
 * @brief  
 *   
 **/  
  
#include   
#include   
#include   
using namespace std;  
  
class Prototype{  
public:  
    Prototype(){_myself = "Prototype";}  
  
    ~Prototype(){}  
    void ShowMyself(){  
        cout<<"I am "<<_myself<"<<_R<<":"<<_G<<":"<<_B<SetRGB(other.GetR(),other.GetG(), other.GetB());      
    }  
  
    virtual Colour * Clone(){  
        return new Colour(*this);  
    }  
private:  
    int _R;  
    int _G;  
    int _B;  
  
};  
  
//Type prototype for all colours  
class Type:public Prototype{  
public:  
    Type(){  
        SetTypeStr("0,0;");  
        SetMyself("Type");  
    }  
    ~Type(){}  
      
    void SetTypeStr(string type){  
        _type_str = type;  
    }  
      
    string GetTypeStr() const{return _type_str;}  
  
    void Print(){  
        cout<<"type:"<<_type_str<SetTypeStr(other.GetTypeStr());      
    }  
  
    virtual Type * Clone(){  
        return new Type(*this);  
    }  
private:  
    string _type_str;  
  
};  
  
class PrototypeMapManager{  
public:  
    PrototypeMapManager(){}  
    ~PrototypeMapManager(){}  
    int RegisterPrototype(string name, Prototype * prototype){  
        map::iterator iter = _prototype_map.find(name);  
        if (iter != _prototype_map.end()){  
            cout<<"prototype["<(name, prototype));  
        return 0;  
    }  
  
    Prototype * GetPrototype(string name){  
        map::iterator iter = _prototype_map.find(name);  
          
        if (iter == _prototype_map.end()){  
            cout<<"prototype["<second;  
        }          
    }  
  
  
private:  
    map _prototype_map;  
};  
  
  
  
//client  
int main(){  
      
    //test simple prototype  
    Colour * prototype = new Colour();  
    cout<<"1. prototype:"<Print();      
    Colour * blue = prototype->Clone();  
    cout<<"2. after cloned:"<Print();  
    blue->SetRGB(0,0,255);  
    cout<<"3. after set property:"<Print();  
    delete prototype;  
  
    Type * type_prototype = new Type();  
    Type * line = type_prototype->Clone();  
    line->SetTypeStr("0,0;99,99;");  
    cout<<"4. line:"<Print();  
      
    //test dynamic produce objects  
    cout<SetMyself("Blue");  
    ProtoMgr.RegisterPrototype("Blue", blue);  
    ProtoMgr.RegisterPrototype("Type", type_prototype);  
    line->SetMyself("Line");  
    ProtoMgr.RegisterPrototype("Line", line);  
  
  
    Prototype * clr_proto = ProtoMgr.GetPrototype("Colour");  
    clr_proto->ShowMyself();  
    Prototype * blue_proto = ProtoMgr.GetPrototype("Blue");  
    blue_proto->ShowMyself();  
    Prototype * red_proto = blue_proto->Clone();  
    red_proto->SetMyself("Red");  
    red_proto->ShowMyself();  
  
    Prototype * line_proto = ProtoMgr.GetPrototype("Line");  
    line_proto->ShowMyself();  
   
      
    return 0;  
}  
  

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
执行结果如下:
1. prototype:  
R:G:B=>0:0:0  
2. after cloned:  
R:G:B=>0:0:0  
3. after set property:  
R:G:B=>0:0:255  
4. line:  
type:0,0;99,99;  
  
DYNAMIC produce TEST  
I am Colour  
I am Blue  
I am Red  
I am Line  

prototype比较麻烦的一点就是clone操作的定义有时候不是那么容易的。涉及到深浅拷贝等问题。具体网上有很多讨论,这里就不抄袭了。对于简单类这个其实也不是什么困难事。