原型模式

2014-11-23 22:57:53 · 作者: · 浏览: 4
原型模式,如其名称,核心就是要实现一个原型类,该类支持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操作的定义有时候不是那么容易的。涉及到深浅拷贝等问题。具体网上有很多讨论,这里就不抄袭了。对于简单类这个其实也不是什么困难事。