c++ 设计模式--原型模式(08)

案例:小韩和小梅去民政局领结婚证(结婚照片),民政局需要出示小韩和小梅分别出示身份证(身份照片)和户口簿(户口照片)

原型模式(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值