第9章原型模式

一 概念与说明

  • 原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  • 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

二 UML结构图

三 需求与C++代码实现

  • 需求
    考虑这样一个实际应用:有一家制造业MRP系统里面有一个工件包的概念,制造型企业对于工件包中的每一个工件每天都有一个核查的需求,每当工件超过 200 项的时候,就需要将 这个工件包拆成两份,如果还是超过200,继续拆分,直到单个数量不超 过200。原因是后续阶段,该企业的生产部门对于工件的设计和进行人工处理,每个人每天处理工件的上限 200个。起始,这个企业遇到的工件基本类型有国内企业和海外企业,我们把这个工件包需求定义成两种类型:HomeOrder和AboradOrder

  • C++代码实现

#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

template <typename elemType>
string iToStr(elemType value)
{
	stringstream ss;
	ss << value;
	return ss.str();
}

class OrderApi
{
public:
	virtual int getOrderProductNum() = 0;
	virtual void setOrderProductNum(int num) = 0;
	virtual string getOrderContent() = 0;
protected:
	OrderApi() {}
};

class HomeOrder : public OrderApi
{
public:
	int getOrderProductNum() override  //获取当前产品的数量
	{
		return this->m_orderProductNum;
	}
	void setOrderProductNum(int num) override
	{
		this->m_orderProductNum = num;
	}
	string getOrderContent() override
	{
		return " 本次订单的客户是:" + this->m_strCustomerName + " 订单数量是: " + iToStr(this->m_orderProductNum);
	}
	void setCustomerName(const string str)
	{
		this->m_strCustomerName = str;
	}
	string getCustomerName() const
	{
		return this->m_strCustomerName;
	}
	void setCustomerId(const string id)
	{
		this->m_strProductId = id;
	}
	string getCustomerId() const
	{
		return this->m_strProductId;
	}
private:
	string m_strCustomerName;  //下订单的用户的名称
	string m_strProductId;  //产品的ID
	int m_orderProductNum;  //产品的数量
};


class AboardOrder : public OrderApi
{
public:
	int getOrderProductNum() override  //获取当前产品的数量
	{
		return this->m_orderProductNum;
	}
	void setOrderProductNum(int num) override
	{
		this->m_orderProductNum = num;
	}
	string getOrderContent() override
	{
		return " 本次订单的客户是:" + this->m_strCustomerName + " 订单数量是: " + iToStr(this->m_orderProductNum);
	}
	void setCustomerName(const string str)
	{
		this->m_strCustomerName = str;
	}
	string getCustomerName() const
	{
		return this->m_strCustomerName;
	}
	void setCustomerId(const string id)
	{
		this->m_strProductId = id;
	}
	string getCustomerId() const
	{
		return this->m_strProductId;
	}
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};

class OrderBusiness
{
public:
	void saveOrder(OrderApi* pOrder);
};

void OrderBusiness::saveOrder(OrderApi * pOrder)
{
	//判断一个工件的数量是否超过200
	while (pOrder->getOrderProductNum() > 200)
	{
		OrderApi* pNewOrder = nullptr;
		if (dynamic_cast<HomeOrder*>(pOrder) != nullptr)
		{
			//创建一个新的对象,去暂存我们的目标
			HomeOrder* p2 = new HomeOrder;
			//赋值对象
			HomeOrder* p1 = static_cast<HomeOrder*>(pOrder);
			p2->setCustomerId(p1->getCustomerId());
			p2->setCustomerName(p1->getCustomerName());
			p2->setOrderProductNum(200);
			pNewOrder = p2;
		}
		if (dynamic_cast<AboardOrder*>(pOrder) != nullptr)
		{
			//创建一个新的对象,去暂存我们的目标
			AboardOrder* p2 = new AboardOrder;
			//赋值对象
			AboardOrder* p1 = static_cast<AboardOrder*>(pOrder);
			p2->setCustomerId(p1->getCustomerId());
			p2->setCustomerName(p1->getCustomerName());
			p2->setOrderProductNum(200);
			pNewOrder = p2;
		}
		//原来的订单还是要保留,但是数量要减少200
		pOrder->setOrderProductNum(pOrder->getOrderProductNum() - 200);
		cout << "新订单是" << pNewOrder->getOrderContent() << endl;
	}
	cout << "最终的订单是" << pOrder->getOrderProductNum() << endl;
}


int main()
{
	HomeOrder* pHome = new HomeOrder;
	pHome->setCustomerName("HIT_3022");
	pHome->setCustomerId("Linux程序设计");
	pHome->setOrderProductNum(512);
	OrderBusiness* pOb = new OrderBusiness();
	pOb->saveOrder(pHome);
	system("pause");
	return 0;
}

思考上面的代码,其中存在一些冗余,现在使用原型模式来重构代码下面的代码片段

if (dynamic_cast<HomeOrder*>(pOrder) != nullptr)
{
	//创建一个新的对象,去暂存我们的目标
	HomeOrder* p2 = new HomeOrder;
	//赋值对象
	HomeOrder* p1 = static_cast<HomeOrder*>(pOrder);
	p2->setCustomerId(p1->getCustomerId());
	p2->setCustomerName(p1->getCustomerName());
	p2->setOrderProductNum(200);
	pNewOrder = p2;
}
if (dynamic_cast<AboardOrder*>(pOrder) != nullptr)
{
	//创建一个新的对象,去暂存我们的目标
	AboardOrder* p2 = new AboardOrder;
	//赋值对象
	AboardOrder* p1 = static_cast<AboardOrder*>(pOrder);
	p2->setCustomerId(p1->getCustomerId());
	p2->setCustomerName(p1->getCustomerName());
	p2->setOrderProductNum(200);
	pNewOrder = p2;
}
  • 使用原型模式后的代码
#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

template <typename elemType>
string iToStr(elemType value)
{
	stringstream ss;
	ss << value;
	return ss.str();
}

class OrderApi
{
public:
	virtual int getOrderProductNum() = 0;
	virtual void setOrderProductNum(int num) = 0;
	virtual string getOrderContent() = 0;
	virtual OrderApi* cloneOrder() = 0;
protected:
	OrderApi() {}
};

class HomeOrder : public OrderApi
{
public:
	int getOrderProductNum() override  //获取当前产品的数量
	{
		return this->m_orderProductNum;
	}
	void setOrderProductNum(int num) override
	{
		this->m_orderProductNum = num;
	}
	string getOrderContent() override
	{
		return " 本次订单的客户是:" + this->m_strCustomerName + " 订单数量是: " + iToStr(this->m_orderProductNum);
	}
	OrderApi* cloneOrder();
	void setCustomerName(const string str)
	{
		this->m_strCustomerName = str;
	}
	string getCustomerName() const
	{
		return this->m_strCustomerName;
	}
	void setCustomerId(const string id)
	{
		this->m_strProductId = id;
	}
	string getCustomerId() const
	{
		return this->m_strProductId;
	}
private:
	string m_strCustomerName;  //下订单的用户的名称
	string m_strProductId;  //产品的ID
	int m_orderProductNum;  //产品的数量
};


class AboardOrder : public OrderApi
{
public:
	int getOrderProductNum() override  //获取当前产品的数量
	{
		return this->m_orderProductNum;
	}
	void setOrderProductNum(int num) override
	{
		this->m_orderProductNum = num;
	}
	string getOrderContent() override
	{
		return " 本次订单的客户是:" + this->m_strCustomerName + " 订单数量是: " + iToStr(this->m_orderProductNum);
	}
	void setCustomerName(const string str)
	{
		this->m_strCustomerName = str;
	}
	string getCustomerName() const
	{
		return this->m_strCustomerName;
	}
	void setCustomerId(const string id)
	{
		this->m_strProductId = id;
	}
	string getCustomerId() const
	{
		return this->m_strProductId;
	}
	OrderApi* cloneOrder();
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};

class OrderBusiness
{
public:
	void saveOrder(OrderApi* pOrder);
};

void OrderBusiness::saveOrder(OrderApi * pOrder)
{
	//判断一个工件的数量是否超过200
	while (pOrder->getOrderProductNum() > 200)
	{
		//新建一个订单
		OrderApi* pNewOrder = pOrder->cloneOrder();        
		//原来的订单还是要保留,但是数量要减少200
		pOrder->setOrderProductNum(pOrder->getOrderProductNum() - 200);
		cout << "新订单是" << pNewOrder->getOrderContent() << endl;
	}
	cout << "最终的订单是" << pOrder->getOrderProductNum() << endl;
}


int main()
{
	AboardOrder* pHome = new AboardOrder;
	pHome->setCustomerName("HIT_3022");
	pHome->setCustomerId("Linux程序设计");
	pHome->setOrderProductNum(512);
	OrderBusiness* pOb = new OrderBusiness();
	pOb->saveOrder(pHome);
	system("pause");
	return 0;
}

OrderApi * HomeOrder::cloneOrder()
{
	HomeOrder* pHomeOrder = new HomeOrder;
	pHomeOrder->setCustomerName(this->m_strCustomerName);
	pHomeOrder->setCustomerId(this->m_strProductId);
	pHomeOrder->setOrderProductNum(this->m_orderProductNum);
	return pHomeOrder;
}

OrderApi * AboardOrder::cloneOrder()
{
	AboardOrder* pHomeOrder = new AboardOrder;
	pHomeOrder->setCustomerName(this->m_strCustomerName);
	pHomeOrder->setCustomerId(this->m_strProductId);
	pHomeOrder->setOrderProductNum(this->m_orderProductNum);
	return pHomeOrder;
}

原文地址:https://www.cnblogs.com/Manual-Linux/p/11125128.html