当前位置:编程学习 > C/C++ >>

原型模式

原型模式,如其名称,核心就是要实现一个原型类,该类支持clone操作,从而客户可以从原型克隆出具体的类。
 
其效果主要有如下:
 
可以动态增加和删除产品。这个就是通过clone代替new等操作,也避免了客户与具体类打交道。
 
通过改变对象的值,指定新的对象。clone出一个新对象后可以修改其参数改变对象,如果参数较多,可以提供类似initialize方法。
 
减少creator类,减少子类数目。客户看起来直接从一个原型克隆出一个新的对象,而不是跟工厂方法打交道,因而少了一个类层次。
 
动态配置应用,这个真是没想明白。也没个例子,我想大致意思就是将原型编译成动态库等,初始化阶段构造原型对象,运行时从原型克隆出新的类吧。
 
写了个简单demo,供参考:
 
 
/** 
 * @file test_prototype.cpp 
 * @author itegel 
 * @date 2013/09/18 15:15:26 
 * @brief  
 *   
 **/  
  
#include <iostream>  
#include <string>  
#include <map>  
using namespace std;  
  
class Prototype{  
public:  
    Prototype(){_myself = "Prototype";}  
  
    ~Prototype(){}  
    void ShowMyself(){  
        cout<<"I am "<<_myself<<endl;  
    }  
    void SetMyself(string str){  
        _myself = str;  
    }  
    virtual Prototype * Clone() = 0;  
private:  
    string _myself;  
};  
  
//Colour prototype for all colours  
class Colour:public Prototype{  
public:  
    Colour(){  
        SetRGB(0,0,0);  
        SetMyself("Colour");  
    }  
    ~Colour(){}  
      
    void SetRGB(int r, int g, int b){  
        _R = r;  
        _G = g;  
        _B = b;  
    }  
  
    int GetR() const {return _R;}  
    int GetG() const {return _G;}  
    int GetB() const {return _B;}  
  
    void Print(){  
        cout<<"R:G:B=>"<<_R<<":"<<_G<<":"<<_B<<endl;  
    }  
      
    Colour(const Colour& other){  
        this->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<<endl;  
    }  
      
    Type(const Type& other){  
        this->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<string, Prototype *>::iterator iter = _prototype_map.find(name);  
        if (iter != _prototype_map.end()){  
            cout<<"prototype["<<name<<"] already exist!"<<endl;  
            return -1;  
        }  
        _prototype_map.insert(pair<string, Prototype *>(name, prototype));  
        return 0;  
    }  
  
    Prototype * GetPrototype(string name){  
        map<string, Prototype *>::iterator iter = _prototype_map.find(name);  
          
        if (iter == _prototype_map.end()){  
            cout<<"prototype["<<name<<"] not find!"<<endl;  
            return NULL;  
        } else {  
            return iter->second;  
        }          
    }  
  
  
private:  
    map<string, Prototype *> _prototype_map;  
};  
  
  
  
//client  
int main(){  
      
    //test 易做图 prototype  
    Colour * prototype = new Colour();  
    cout<<"1. prototype:"<<endl;  
    prototype->Print();      
    Colour * blue = prototype->Clone();  
    cout<<"2. after cloned:"<<endl;  
    blue->Print();  
    blue->SetRGB(0,0,255);  
    cout<<"3. after set property:"<<endl;  
    blue->Print();  
    delete prototype;  
  
    Type * type_prototype = new Type();  
    Type * line = type_prototype->Clone();  
    line->SetTypeStr("0,0;99,99;");  
    cout<<"4. line:"<<endl;  
    line->Print();  
      
    //test dynamic produce objects  
    cout<<endl;  
    cout<<"DYNAMIC produce TEST"<<endl;  
    PrototypeMapManager ProtoMgr;  
    Colour * colour_prototype = new Colour();  
    ProtoMgr.RegisterPrototype("Colour", colour_prototype);  
    blue->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操作的定义有时候不是那么容易的。涉及到深浅拷贝等问题。具体网上有很多讨论,这里就不抄袭了。对于简单类这个其实也不是什么困难事。
 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,