原型模式

一. 原型模式简介
  
原型模式(Prototype Pattern)也是一种创建型模式,它关注的是大量相似对象的创建问题。我们经常会遇到这样的情况:在系统中要创建大量的对象,这些对象之间具有几乎完全相同的功能,只是在细节上有一点儿差别。
   这样的情形经常遇到。三国系列游戏是我最喜欢的游戏系列之一。你有没有注意到那里边上百位英雄的头像基本上很相似?你仔细区分就会发现,虽然每个人都不同,但基本上只具有几种脸型:长方的、圆形的、细长的,然后配上不同的胡子、眉毛、眼睛、嘴,有的再加点儿伤疤或装饰物(比如给独眼龙夏侯敦加个单眼罩),就成了不同的人物头像!那么,为什么会这样的?因为根据研究表明,人类的脸谱基本上只有有限的几个类型,只不过在细节和组合方面存在些许差异。游戏制作者具有依据这个理论,只对人脸进行有限的几种建模,然后再通过组合、修饰,就可以产生无数的头像了。

  用面向对象的方法来说就是,我们先建立一个原型,然后通过对原型进行复制和修饰的方法,就可以产生一个和原型相似的新对象。用GoF的话来说就是:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

二. 原型模式实例
  前几天,我很不幸把屋门的钥匙给弄丢了,结果进不了家门。万幸的是,GF那儿还有一把,于是第二天我拿了她的那把去配钥匙。另外,她还让我顺便给她配一把橱柜的钥匙。现在配个钥匙真是简单,把钥匙给他,他直接找一个合适的钥匙胚子,把我的钥匙夹在配钥匙机的一端,胚子夹在另一端,一开电源,一把标尺比着我的钥匙齿型走一遍,砂轮就在胚子上复制出一把钥匙来!一分钟不到,两把新钥匙就搞定了!
       用OO来描述,我的    
  旧钥匙是一个原型。配钥匙的过程就是根据我提供的原型,再复制一份出来,就有了一个新的钥匙。两个钥匙完全一样,我也可以给新配的钥匙贴个标签,以表明是“我的”。用这样的方法,我可以对各种钥匙进行复制,也可以复制无限多份。OO分析的类图如下:
 

三.C++中的原型模式

结构
 
理解
1.        Prototype 是原型基类,提供Clone 纯虚方法,它根据不同的派生类来克隆不同的对象。
2.        ConcretePrototype 是原型具体类。实现Clone 方法,克隆自己,返回克隆后的新对象。
3.        Client 调用基类Clone 接口,就可以得到一个克隆对象。
要点
1.         原型模式中,Client 并不知道要克隆对象的实际类型,只需知道基类类型即可。
2.         克隆对象比直接创建对象的优点在于,克隆是将原有对象的行为属性带到了新的对象中。
3.        C++ 没有克隆方法,要克隆一个对象,需要借助拷贝构造函数Copy Constructor )来实现。拷贝构造函数中实现拷贝对象有浅拷贝深拷贝
浅拷贝 是指对象复制时,只是对于对象中的数据成员进行值拷贝;深拷贝是指对象赋值时,对于对象的简单数据成员进行值拷贝,对于对象中的动态成员(堆或者其他系统资源),要重新分配动态空间。
当类不定义拷贝构造函数的时候,编译器会自动生一个构造函数,叫做默认拷贝构造函数。默认拷贝构造函数使用浅拷贝方式。如果类中含有动态数据成员,就必须使用深拷贝方式实现拷贝构造函数,否则,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,产生运行时错误。
 
应用
源码中,Line 是原型基类,具体克隆类是直线和曲线。
 
源码
#include  <iostream>
#include  <string>
using  namespace std;
 
// 原型基类 线条
class  CLinePrototype
{
public :
    virtual ~CLinePrototype(){};
 
    virtual CLinePrototypeClone() = 0;
};
 
// 原型具体类 直线
class  CBeelinePrototype : public CLinePrototype
{
public :
    CBeelinePrototype(){};
    // 拷贝构造函数
    CBeelinePrototype(const CBeelinePrototype &o)
    {
        this->m_iWeight = o.m_iWeight;
    }
 
    virtual ~CBeelinePrototype(){};
 
    virtual CLinePrototypeClone()
    {
        cout << "clone a line" << endl;
        return new CBeelinePrototype(*this);
    }
 
    void SetWeight(const int &iWeight)
    {
        this->m_iWeight = iWeight;
   }
    void Print()
    {
        cout << "beeline weight: " << m_iWeight << endl;
    }
 
protected :
    int m_iWeight;
};
 
// 原型具体类 曲线
class  CCurvePrototype : public CLinePrototype
{
public :
    CCurvePrototype(){};
    // 拷贝构造函数
    CCurvePrototype(const CCurvePrototype &o)
    {
        this->m_strType = o.m_strType;
    }
 
    virtual ~CCurvePrototype(){};
 
    virtual CLinePrototypeClone()
    {
        cout << "clone a curve" << endl;
        return new CCurvePrototype(*this);
    }
 
    void SetType(const string &m_strType)
    {
        this->m_strType = m_strType;
    }
    void Print()
    {
        cout << "beeline type: " << m_strType.c_str() << endl;
    }
 
protected :
    string m_strType;
};
 
//Client
CLinePrototype Clone(CLinePrototypepPrototype)
{
    return pPrototype->Clone();
}
 
 
int  main()
{
    CBeelinePrototypep1 = new CBeelinePrototype();
    p1->SetWeight(10);
    CLinePrototypep1Clone = Clone(p1);
    CBeelinePrototypep1Clone1 = dynamic_cast<CBeelinePrototype*>(p1Clone);
    p1Clone1->Print();
 
    CCurvePrototypep2 = new CCurvePrototype();
    p2->SetType("DOT");
    CLinePrototypep2Clone = Clone(p2);
    CCurvePrototypep2Clone1 = dynamic_cast<CCurvePrototype*>(p2Clone);
    p2Clone1->Print();
 
    system("pause");
    return 0;
}
 
输出:
clone a line
beeline weight: 10
clone a curve
beeline type: DOT


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值