案例:小韩和小梅去民政局领结婚证(结婚照片),民政局需要出示小韩和小梅分别出示身份证(身份照片)和户口簿(户口照片)
原型模式(Prototype)
原型模式定义
原型模式是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式结构
- 抽象原型类(AbstractPrototype):声明克隆Clone自身的接口
- 具体原型类(ConcretePrototype):实现Clone接口
- 客户端(Client):客户端通过抽象原型类中静态方法Clone具体原型类对象实例
注: 静态成员和静态方法应标记横线
原型模式示例
https://gitee.com/NiMiKiss/design-pattern.git
#ifndef _PROTOTYPE_PATTERN_
#define _PROTOTYPE_PATTERN_
#include<iostream>
#include<map>
#include<vector>
enum PhotoType
{
ID = 1,
HOUSEHOLD,
WEDDING
};
enum PhotoSize
{
SMALL = 1,
MIDDLE,
LARGE
};
enum BackgroundColor
{
WHITE = 1,
BLUE,
RED
};
namespace
{
std::string TranslatePhotoSizeEnmuToString(PhotoSize ePhotoSize)
{
switch (ePhotoSize)
{
case SMALL:
return "Small";
break;
case MIDDLE:
return "Middle";
break;
case LARGE:
return "Large";
break;
default:
return "";
break;
}
}
std::string TranslateBackgroundColorEnmuToString(BackgroundColor eBackgroundColor)
{
switch (eBackgroundColor)
{
case WHITE:
return "white";
break;
case BLUE:
return "Blue";
break;
case RED:
return "Red";
break;
default:
return "";
break;
}
}
}
class Person
{
public:
Person(const std::string& sName = "", const std::string& sSex = "") :m_sName(sName), m_sSex(sSex) {}
void SetName(const std::string& sName) { m_sName = sName; }
std::string GetName()const { return m_sName; }
void SetSex(const std::string& sSex) { m_sSex = sSex; }
std::string GetSex()const { return m_sSex; }
private:
std::string m_sName;
std::string m_sSex;
};
class IPhoto
{
public:
virtual void DisplayPhoto() = 0;
virtual void SetBackGroundColor(const BackgroundColor&) = 0;
virtual void SetPhotoSize(const PhotoSize&) = 0;
virtual std::shared_ptr<IPhoto> Clone() = 0;
virtual void SetPerson(const std::vector<Person>&) {};
virtual void SetPerson(const Person&) {};
static std::shared_ptr<IPhoto> FindAndClone(const PhotoType& ePhotoType)
{
if (m_mapPhotos.find(ePhotoType) != m_mapPhotos.end())
{
return m_mapPhotos[ePhotoType]->Clone();
}
return nullptr;
}
static void AddPrototype(const PhotoType& ePhotoType, IPhoto* spPhoto)
{
if (m_mapPhotos.find(ePhotoType) == m_mapPhotos.end())
{
m_mapPhotos.insert(std::make_pair(ePhotoType, spPhoto));
}
}
private:
static std::map<PhotoType, IPhoto*> m_mapPhotos;
};
std::map<PhotoType, IPhoto*>IPhoto::m_mapPhotos;
class IDPhoto :public IPhoto
{
public:
void DisplayPhoto()
{
std::cout << "身份证照片信息: " << std::endl;
std::cout << "照片大小: " << TranslatePhotoSizeEnmuToString(m_PhotoSize)
<< " 照片背景: " << TranslateBackgroundColorEnmuToString(m_BackgroundColor)
<< " 照片人物姓名: " << m_spPerson->GetName()
<< " 照片人物性别: " << m_spPerson->GetSex() << std::endl;
}
void SetPerson(const Person& person)
{
m_spPerson->SetName(person.GetName());
m_spPerson->SetSex(person.GetSex());
}
void SetBackGroundColor(const BackgroundColor& eBackgroundColor)
{
m_BackgroundColor = eBackgroundColor;
}
void SetPhotoSize(const PhotoSize& ePhotoSize)
{
m_PhotoSize = ePhotoSize;
}
std::shared_ptr<IPhoto> Clone()
{
return std::shared_ptr<IDPhoto>(new IDPhoto(1));
}
private:
PhotoSize m_PhotoSize;
BackgroundColor m_BackgroundColor;
std::shared_ptr<Person> m_spPerson;
private:
PhotoType GetPhotoType() { return ID; }
IDPhoto()
{
m_PhotoSize = SMALL;
m_BackgroundColor = WHITE;
m_spPerson = std::shared_ptr<Person>(new Person());
AddPrototype(GetPhotoType(), this);
}
IDPhoto(int)
{
m_PhotoSize = m_IDPhoto.m_PhotoSize;
m_BackgroundColor = m_IDPhoto.m_BackgroundColor;
m_spPerson = std::shared_ptr<Person>(new Person());
}
static IDPhoto m_IDPhoto;
};
IDPhoto IDPhoto::m_IDPhoto;
class HouseholdPhoto :public IPhoto
{
public:
void DisplayPhoto()
{
std::cout << "户口薄照片信息: " << std::endl;
std::cout << "照片大小: " << TranslatePhotoSizeEnmuToString(m_PhotoSize)
<< " 照片背景: " << TranslateBackgroundColorEnmuToString(m_BackgroundColor)
<< " 照片人物姓名: " << m_spPerson->GetName()
<< " 照片人物性别: " << m_spPerson->GetSex() << std::endl;
}
void SetPerson(const Person& person)
{
m_spPerson->SetName(person.GetName());
m_spPerson->SetSex(person.GetSex());
}
void SetBackGroundColor(const BackgroundColor& eBackgroundColor)
{
m_BackgroundColor = eBackgroundColor;
}
void SetPhotoSize(const PhotoSize& ePhotoSize)
{
m_PhotoSize = ePhotoSize;
}
std::shared_ptr<IPhoto> Clone()
{
return std::shared_ptr<HouseholdPhoto>(new HouseholdPhoto(1));
}
private:
PhotoSize m_PhotoSize;
BackgroundColor m_BackgroundColor;
std::shared_ptr<Person> m_spPerson;
private:
PhotoType GetPhotoType() { return HOUSEHOLD; }
HouseholdPhoto()
{
m_PhotoSize = MIDDLE;
m_BackgroundColor = BLUE;
m_spPerson = std::shared_ptr<Person>(new Person());
AddPrototype(GetPhotoType(), this);
}
HouseholdPhoto(int)
{
m_PhotoSize = m_HouseholdPhoto.m_PhotoSize;
m_BackgroundColor = m_HouseholdPhoto.m_BackgroundColor;
m_spPerson = std::shared_ptr<Person>(new Person());
}
static HouseholdPhoto m_HouseholdPhoto;
};
HouseholdPhoto HouseholdPhoto::m_HouseholdPhoto;
class WeddingPhoto :public IPhoto
{
public:
void DisplayPhoto()
{
std::cout << "结婚证照片信息: " << std::endl;
std::cout << "照片大小: " << TranslatePhotoSizeEnmuToString(m_PhotoSize)
<< " 照片背景: " << TranslateBackgroundColorEnmuToString(m_BackgroundColor);
for (size_t i = 0; i < 2; i++)
{
std::cout << " 照片人物姓名: " << m_spPerson[i]->GetName()
<< " 照片人物性别: " << m_spPerson[i]->GetSex();
}
std::cout << std::endl;
}
void SetPerson(const std::vector<Person>& vecPerson)
{
if (vecPerson.size() == 2)
{
for (size_t i = 0; i < 2; i++)
{
m_spPerson[i]->SetName(vecPerson[i].GetName());
m_spPerson[i]->SetSex(vecPerson[i].GetSex());
}
}
}
void SetBackGroundColor(const BackgroundColor& eBackgroundColor)
{
m_BackgroundColor = eBackgroundColor;
}
void SetPhotoSize(const PhotoSize& ePhotoSize)
{
m_PhotoSize = ePhotoSize;
}
std::shared_ptr<IPhoto> Clone()
{
return std::shared_ptr<WeddingPhoto>(new WeddingPhoto(1));
}
private:
PhotoSize m_PhotoSize;
BackgroundColor m_BackgroundColor;
std::shared_ptr<Person> m_spPerson[2];
private:
PhotoType GetPhotoType() { return WEDDING; }
WeddingPhoto()
{
m_PhotoSize = LARGE;
m_BackgroundColor = RED;
m_spPerson[0] = std::shared_ptr<Person>(new Person());
m_spPerson[1] = std::shared_ptr<Person>(new Person());
AddPrototype(GetPhotoType(), this);
}
WeddingPhoto(int)
{
m_PhotoSize = m_WeddingPhoto.m_PhotoSize;
m_BackgroundColor = m_WeddingPhoto.m_BackgroundColor;
m_spPerson[0] = std::shared_ptr<Person>(new Person());
m_spPerson[1] = std::shared_ptr<Person>(new Person());
}
static WeddingPhoto m_WeddingPhoto;
};
WeddingPhoto WeddingPhoto::m_WeddingPhoto;
#endif // !_PROTOTYPE_PATTERN_
客户端调用
#include "Prototype_Pattern.h"
#include<iostream>
int main()
{
auto spIDPhoto_0 = IPhoto::FindAndClone(ID);
spIDPhoto_0->SetPerson(Person("小韩","男"));
spIDPhoto_0->DisplayPhoto();
auto spIDPhoto_1 = spIDPhoto_0->Clone();
spIDPhoto_1->SetPerson(Person("小梅", "女"));
spIDPhoto_1->DisplayPhoto();
auto spHousePhoto_0 = IPhoto::FindAndClone(HOUSEHOLD);
spHousePhoto_0->SetPerson(Person("小韩", "男"));
spHousePhoto_0->DisplayPhoto();
auto spHousePhoto_1 = spHousePhoto_0->Clone();
spHousePhoto_1->SetPerson(Person("小梅", "女"));
spHousePhoto_1->DisplayPhoto();
std::vector<Person> vecPerson{ Person("小韩", "男") ,Person("小梅", "女") };
auto spWeddingPhoto = IPhoto::FindAndClone(WEDDING);
spWeddingPhoto->SetPerson(vecPerson);
spWeddingPhoto->DisplayPhoto();
return EXIT_SUCCESS;
}