一 概念与说明
- 原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
二 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;
}