C++设计模式 ——prototype pattern
一、定义
根据保存的原型寻找需创建对象的类型,再通过拷贝(clone)依据类型创建新的对象。
二、结构
三、要点
- 原型模式中,Client并不知道要克隆对象的实际类型,只需知道基类类型即可。
- 克隆对象比直接创建对象的优点在于,克隆是将原有对象的行为属性带到了新的对象中。
- C++没有克隆方法,要克隆一个对象,需要借助拷贝构造函数(Copy Constructor)来实现。拷贝构造函数中实现拷贝对象有浅拷贝和深拷贝。
四、代码
1. prototype.h
#ifndef PROTOTYPE_H
#define PROTOTYPE_H
#include <iostream>
using namespace std;
enum imageType
{
LSAT,SPOT
};
class Image
{
public:
virtual void draw()=0;
static Image *findAndClone(imageType);
protected:
virtual imageType returnType()=0;
virtual Image *clone()=0;
// As each subclass of Image is declared,it registers its prototype
static void addPrototype(Image *image)
{
_prototypes[_nextSlot++] = image;
}
private:
// addPrototype() saves each registered prototype here
static Image *_prototypes[10];
static int _nextSlot;
};
Image *Image::_prototypes[];
int Image::_nextSlot;
// Client calls this public static member function when it needs an instance of an Image subclass
Image *Image::findAndClone(imageType type)
{
for(int i=0;i<_nextSlot;i++)
if(_prototypes[i]->returnType()==type)
return _prototypes[i]->clone();
}
class LandSatImage:public Image
{
public:
imageType returnType(){
return LSAT;
}
void draw(){
cout <<"LandSatImage::draw"<<_id<<endl;
}
// When clone()is called,call the one-argument ctor with a dummy arg
Image *clone(){
return new LandSatImage(1);
}
protected:
//This is only called from clone()
LandSatImage(int dummy){
_id=_count++;
}
private:
//Mechanism for initializing an Image subclass-this causes the
// default ctor to be called,which registers the subclasss prototype
static LandSatImage _landSatImage;
//This is only called yhen the private static data member is inited
LandSatImage()
{
addPrototype(this);
}
// Nominal "state" per instance mechanism
int _id;
static int _count;
};
// Register the subclasss prototype
LandSatImage LandSatImage::_landSatImage;
// Initialize the"state" per instance mechanism
int LandSatImage::_count = 1;
class SpotImage:public Image
{
public:
imageType 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;
#endif
2. prototype.cpp
#include "prototype.h"
// Simulated stream of creation requests
const int NUM_IMAGES=8;
imageType input[NUM_IMAGES]=
{
LSAT,LSAT,LSAT,SPOT,LSAT,SPOT,SPOT,LSAT
};
int main()
{
Image *images[NUM_IMAGES];
// Given an image type,find the right prototype,and return a clone
for(int i=0;i<NUM_IMAGES;i++)
images[i]=Image::findAndClone(input[i]);
//Demonstrate that correct image objects have been cloned
for(int i=0;i<NUM_IMAGES;i++)
images[i]->draw();
// Free the dynamic memory
for(int i=0;i<NUM_IMAGES;i++)
delete images[i];
return 0;
}
下一篇:
迷宫c++利用栈空间回溯法
