微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

原型模式(Prototype)

原型模式(Prototype

 

原型模式(Prototype

意图:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。

应用Java/C#中的ClonableIClonable接口等。

模式结构

心得

原型模式本质上就是对象的拷贝,使用对象拷贝代替对象创建的原因有很多。比如对象的初始化构造非常复杂,消耗资源巨大;运行时对象状态变化不可重现;无法获得对象的成员的运行时值等。实现原型模式关键在于对象的正确复制,因此像高级语言实现的那样——支持复制接口。而对象的复制分为“深复制”和“浅复制”,前者除了复制对象本身数据外,还需要复制对象内指针引用的数据,后者则是仅仅复制对象数据。另外,深度复制如果遇到循环引用的对象就会产生问题。

举例

按照上述设计,这里实现模式的代码如下:

//基本原型接口——相当于Clonable
class Prototype
{
public:
    virtual Prototype* Clone()=0;
    virtual ~Prototype(){}
};
//原型管理器
class PrototypeMgr
{
    hash_map<char*,Prototype*>map;
public:
    void regProto(char* key,Prototype*p)
    {
        if(map.find(key)!=map.end())
        {
            delete map[key];
        }
        map[key]=p;
    }
    Prototype* const operator[](char* key)
    {
        if(map.find(key)!=map.end())
        {
            return map[key]->Clone();
        }
        else
            return NULL;
    }
    ~PrototypeMgr()
    {
        for(hash_map<char*,Prototype*>::iterator it=map.begin();
            it!=map.end();++it)
        {
            delete it->second;
        }
    }
};
//浅拷贝
class ConcretePrototype1:public Prototype
{
    int * refMember;
    int member;
public:
    virtual Prototype* Clone()
    {
        cout<<"执行ConcretePrototype1的浅复制"<<endl;
        ConcretePrototype1*copy= new ConcretePrototype1;
        copy->member=member;
        copy->refMember=refMember;
        return copy;
    }
};
//深度拷贝
class ConcretePrototype2:public Prototype
{
    int * refMember;
    int member;
public:
    ConcretePrototype2():refMember(new int){}
    virtual Prototype* Clone()
    {
        cout<<"执行ConcretePrototype2的深复制"<<endl;
        ConcretePrototype2*copy= new ConcretePrototype2;
        copy->member=member;
        copy->refMember=new int;//指针引用数据也要拷贝
        *copy->refMember=*refMember;
        return copy;
    }
    virtual~ConcretePrototype2()
    {
        delete refMember;
    }
};

这里添加一个原型管理器,用来管理所有的注册的原型。用户需要拷贝出原型只需要从这里请求即可。

PrototypeMgr mgr;
//注册原型
mgr.regProto("浅复制",new ConcretePrototype1);
mgr.regProto("深复制",new ConcretePrototype2);
//请求原型
Prototype*cp1=mgr["浅复制"];
Prototype*cp2=mgr["深复制"];
delete cp1;
delete cp2;

参考文章http://zxyjxnu.blog.163.com/blog/static/1330787122007103095839612/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐