原型模式

超、凢脫俗 2022-02-21 12:16 306阅读 0赞

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

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

二. 原型模式实例

  前几天,我很不幸把屋门的钥匙给弄丢了,结果进不了家门。万幸的是,GF那儿还有一把,于是第二天我拿了她的那把去配钥匙。另外,她还让我顺便给她配一把橱柜的钥匙。现在配个钥匙真是简单,把钥匙给他,他直接找一个合适的钥匙胚子,把我的钥匙夹在配钥匙机的一端,胚子夹在另一端,一开电源,一把标尺比着我的钥匙齿型走一遍,砂轮就在胚子上复制出一把钥匙来!一分钟不到,两把新钥匙就搞定了!

5.bmp用OO来描述,我的    

  旧钥匙是一个原型。配钥匙的过程就是根据我提供的原型,再复制一份出来,就有了一个新的钥匙。两个钥匙完全一样,我也可以给新配的钥匙贴个标签,以表明是“我的”。用这样的方法,我可以对各种钥匙进行复制,也可以复制无限多份。OO分析的类图如下:

51.bmp

三.C++中的原型模式

结构

原型模式

理解

  1. Prototype 是原型基类,提供Clone 纯虚方法,它根据不同的派生类来克隆不同的对象。

  2. ConcretePrototype 是原型具体类。实现Clone 方法,克隆自己,返回克隆后的新对象。

  3. Client 调用基类Clone 接口,就可以得到一个克隆对象。

要点

  1. 原型模式中,Client 并不知道要克隆对象的实际类型,只需知道基类类型即可。

  2. 克隆对象比直接创建对象的优点在于,克隆是将原有对象的行为属性带到了新的对象中。

  3. C++ 没有克隆方法,要克隆一个对象,需要借助拷贝构造函数(Copy Constructor )来实现。拷贝构造函数中实现拷贝对象有浅拷贝和深拷贝:

浅拷贝 是指对象复制时,只是对于对象中的数据成员进行值拷贝;深拷贝是指对象赋值时,对于对象的简单数据成员进行值拷贝,对于对象中的动态成员(堆或者其他系统资源),要重新分配动态空间。

当类不定义拷贝构造函数的时候,编译器会自动生一个构造函数,叫做默认拷贝构造函数。默认拷贝构造函数使用浅拷贝方式。如果类中含有动态数据成员,就必须使用深拷贝方式实现拷贝构造函数,否则,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,产生运行时错误。

应用

源码中,Line 是原型基类,具体克隆类是直线和曲线。

源码

#include

#include

using namespace std;

// 原型基类 . 线条

class CLinePrototype

{

public :

virtual ~CLinePrototype(){};

virtual CLinePrototype* Clone() = 0;

};

// 原型具体类 . 直线

class CBeelinePrototype : public CLinePrototype

{

public :

CBeelinePrototype(){};

// 拷贝构造函数

CBeelinePrototype(const CBeelinePrototype &o)

{

this->m_iWeight = o.m_iWeight;

}

virtual ~CBeelinePrototype(){};

virtual CLinePrototype* Clone()

{

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 CLinePrototype* Clone()

{

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(CLinePrototype* pPrototype)

{

return pPrototype->Clone();

}

int main()

{

CBeelinePrototype* p1 = new CBeelinePrototype();

p1->SetWeight(10);

CLinePrototype* p1Clone = Clone(p1);

CBeelinePrototype* p1Clone1 = dynamic_cast(p1Clone);

p1Clone1->Print();

CCurvePrototype* p2 = new CCurvePrototype();

p2->SetType(“DOT”);

CLinePrototype* p2Clone = Clone(p2);

CCurvePrototype* p2Clone1 = dynamic_cast(p2Clone);

p2Clone1->Print();

system(“pause”);

return 0;

}

输出:

clone a line

beeline weight: 10

clone a curve

beeline type: DOT

发表评论

表情:
评论列表 (有 0 条评论,306人围观)

还没有评论,来说两句吧...

相关阅读

    相关 原型模式

    一. 原型模式简介    原型模式(Prototype Pattern)也是一种创建型模式,它关注的是大量相似对象的创建问题。我们经常会遇到这样的情况:在系统中要创建大量的

    相关 原型模式

    对象浅拷贝 实现Clonable接口,重写clone方法,jvm的本地方法实现拷贝 Object protected native Object clone()

    相关 原型模式

    原型模式(Prototype Pattern):通过原型实例指定创建对象的种类,并且通过克隆这些原型来创建新的对象。原型模式是一种创建型模式   完成原型模式一般需要3个角

    相关 原型模式

    原型模式:用原型实例指定创建指定对象的种类,并且通过复制这些原型创建新的对象,同时又能保证性能。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价

    相关 原型模式

    原型模式 定义 在软件系统中,有时需要多次创建某一类型的对象,为了简化创建过程,可以只创建一个对象,然后通过对象克隆的方式复制出多个相同的对象,这就是原型设计模

    相关 原型模式

    型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式是实现了...