【C++】设计模式:prototype 原型模式

/*
代码说明:原型模式示例代码
作用说明:原型模式提供了自我复制的功能,就是说新对象的创建可以通过已有的对象进行创建。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。可以说,拷贝是原型模式的精髓所在。
基本思想:
在找工作的时候,我们需要准备简历,假设没有打印设备,我们需要手写多份简历,这些简历的内容都是一样的,这样有个缺陷,如果想要修改简历中的某项,那么所有已经写好的简历都需要修改,工作量很大.
随着科技的进步,出现了打印设备。我们只需要手写一份,然后利用打印设备复印多份即可。如果要修改简历中的某项,那么修改原始版本就可以,然后再复印。原始的那份手稿相当于一个原型,有了它,通过复印(拷贝)创造出更多的新简历。这就是原型模式的基本思想。
*/

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值