/*
代码说明:原型模式示例代码
作用说明:原型模式提供了自我复制的功能,就是说新对象的创建可以通过已有的对象进行创建。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。可以说,拷贝是原型模式的精髓所在。
基本思想:
在找工作的时候,我们需要准备简历,假设没有打印设备,我们需要手写多份简历,这些简历的内容都是一样的,这样有个缺陷,如果想要修改简历中的某项,那么所有已经写好的简历都需要修改,工作量很大.
随着科技的进步,出现了打印设备。我们只需要手写一份,然后利用打印设备复印多份即可。如果要修改简历中的某项,那么修改原始版本就可以,然后再复印。原始的那份手稿相当于一个原型,有了它,通过复印(拷贝)创造出更多的新简历。这就是原型模式的基本思想。
*/
#include<iostream>
using namespace std;
enum imagType
{
LSAT,SPOT
};//对象的类型
class Image
{
public:
virtual void draw() = 0;
static Image * findAndClone(imagType);//克隆出相应的对象
protected:
virtual imagType returnType() = 0;
virtual Image* clone() = 0;//子类通过重写此函数,以供父类正确的克隆出相应的对象
static void addPrototype(Image* image)
{
_prototypes[_nextSlot++] = image;
}//子类通过此函数将自己注册到父类中
private:
static Image* _prototypes[10];//容量:最多X种对象类型
static int _nextSlot;
};
Image * Image::_prototypes[]{};
int Image::_nextSlot{0};
Image* Image::findAndClone(imagType type)
{
for(int i = 0; i < _nextSlot; i++){
if(_prototypes[i]->returnType() == type){
return _prototypes[i]->clone();
}
}
}//克隆出相应的对象
/*
原型模式的设计精髓之一就是提供了两个构造函数。
1.一种构造函数的类型一定设置为private,在构造时将自己通过父类的addPrototype函数注册到父类中;子类中包含一个自己的static对象,因此编译期间自动构造自己并实现注册。
2.一种构造函数的类型可以设置为protected,为了跟第一种区别,可以设置一个无意义的形参(只设置,不使用),在实际clone的时候调用此构造函数去实现克隆。
*/
class LandSatImage:public Image
{
public:
imagType returnType()
{
return LSAT;
}
void draw()
{
cout<<"LandSatImage"<<_id<<endl;
}
Image* clone()
{
return new LandSatImage(1);
}
protected:
LandSatImage(int dummy)
{
_id = _count++;
}//protected构造函数,实现克隆的时候调用此函数。形参dummy无意义仅用作区分private构造函数。
private:
static LandSatImage _landSatImage;//创建一个自己
LandSatImage()
{
addPrototype(this);
}//private构造函数,static对象实例化的时候自动调用此函数
int _id;
static int _count;
};
LandSatImage LandSatImage::_landSatImage{};
int LandSatImage::_count = 1;//static,自动创建一个对象,因此此处计数为1
class SpotImage:public Image
{
public:
imagType returnType()
{
return SPOT;
}
void draw()
{
cout<<"SpotImage::draw"<<_id<<endl;
}
Image* clone()
{
return new SpotImage(1);
}
protected:
SpotImage(int dummy)
{
_id = _count++;
}
private:
SpotImage()
{
addPrototype(this);
}
static SpotImage _spotImage;
int _id;
static int _count;
};
SpotImage SpotImage::_spotImage{};
int SpotImage::_count = 1;
const int NUM_IMAGES = 8;
imagType input[NUM_IMAGES] =
{
LSAT,LSAT,LSAT,SPOT,LSAT,SPOT,SPOT,SPOT
};
int main()
{
Image* images[NUM_IMAGES];
for(int i = 0; i < NUM_IMAGES; i++)
{
images[i] = Image::findAndClone(input[i]);
}
for(int i = 0; i < NUM_IMAGES; i++)
{
images[i]->draw();
}
for(int i = 0; i < NUM_IMAGES; i++)
{
delete images[i];
}
return 0;
}
【C++】设计模式:prototype 原型模式
最新推荐文章于 2024-05-06 11:04:01 发布