思考原型模式
①原型模型的本质:克隆生成对象
②原型模式可以用来解决“只知接口而不知实现的问题”,出现一种“接口造接口”的假象。
③原型模式的重心还是在创建新的对象实例。至于创建出来的对象,其属性的值是否一定要和原型对象完全一样,这并没有强制规定,但一般会拷贝成一样的。
④通过克隆出来实例是原型实例是两个完全独立的实例,他们之间没有关联。
【编程实验】订单拆分处理
//创建型模式:原型模式//订单处理:/*
功能需求:因每个工作小组的处理能力上限是1000,现要求每当订单预定产品数量超过1000时,
把订单拆分为两份来保存,如果还是超过1000,那就继续拆分,直到不超过1000.
*/
//声明文件
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
//*************************辅助类:************************
//定义产品原型的接口,这个产品是为了演示深拷贝
class CProductPrototype{
private:
string strId;//产品编号
string strName;//产品名称
public:
void SetId(string id);
string GetId();
void SetName(string name);
string GetName();
string ToStr();
CProductPrototype* Clone();//克隆方法
};
//*************************订单原型**************************
//订单的接口,声明了可以克隆自身的方法
class CAbsOrder{
public:
virtual ~CAbsOrder();
virtual string ToStr() = 0;
virtual void SetName(string name) = 0;
virtual string GetName() = 0;
virtual void SetProduct(CProductPrototype* product) = 0;
virtual CProductPrototype* GetProduct() = 0;
virtual void SetProductId(string productid) = 0;
virtual string GetProductId() = 0;
virtual void SetProductNum(int products) = 0;
virtual int GetProductNum() = 0;
virtual CAbsOrder* Clone() = 0;
};
//个人订单对象
class CPersonalOrder : public CAbsOrder{
private:
string strCustomer;
CProductPrototype* pProduct;
string strProductId;
int iProducts;
public:
CPersonalOrder();
~CPersonalOrder();
void SetName(string customer);
string GetName();
void SetProduct(CProductPrototype* product);
CProductPrototype* GetProduct();
void SetProductId(string productid);
string GetProductId();
void SetProductNum(int products);
int GetProductNum();
string ToStr();
CAbsOrder* Clone();
};
//企业订单对象
class CEnterpriseOrder : public CAbsOrder{
private:
string strEnterprise;
CProductPrototype* pProduct;
string strProductId;
int iProducts;
public:
CEnterpriseOrder();
string ToStr();
void SetName(string enterprise);
string GetName();
void SetProduct(CProductPrototype* product);
CProductPrototype* GetProduct();
void SetProductId(string productid);
string GetProductId();
void SetProductNum(int products);
int GetProductNum();
CAbsOrder* Clone();
};
//*********************************订单拆分过程********************
//处理订单
//saveOrder传入的是订单接口类型的对象实例,这里只知道
//订单接口的类型,并不知道其具体类型是个人订单还是企业订单
void OrderDispatch(CAbsOrder* pOrgOrder);
//实现文件
//*************************辅助类:************************
//定义产品原型的接口,这个产品是为了演示深拷贝
void CProductPrototype::SetId(string id){strId = id;}
string CProductPrototype::GetId(){return strId;}
void CProductPrototype::SetName(string name){strName = name;}
string CProductPrototype::GetName(){return strName;}
string CProductPrototype::ToStr(){return "Id : " + strId + ", Name : " + strName + "\n";}
CProductPrototype* CProductPrototype::Clone()//克隆方法
{
//创建一个新的订单,然后把本实例的数据复制过去
CProductPrototype* pProduct = new CProductPrototype();
pProduct->SetId(strId);
pProduct->SetName(strName);
return pProduct;
}
//*************************订单原型**************************
//订单的接口,声明了可以克隆自身的方法
CAbsOrder::~CAbsOrder(){}
//个人订单对象
CPersonalOrder::CPersonalOrder(){pProduct = NULL; iProducts = 0;}
CPersonalOrder::~CPersonalOrder(){cout << "deleting..." << endl << endl; if(pProduct != NULL) delete pProduct;}
void CPersonalOrder::SetName(string customer){strCustomer = customer;}
string CPersonalOrder::GetName(){return strCustomer;}
void CPersonalOrder::SetProduct(CProductPrototype* product){pProduct = product;}
CProductPrototype* CPersonalOrder::GetProduct(){return pProduct;}
void CPersonalOrder::SetProductId(string productid){strProductId = productid;}
string CPersonalOrder::GetProductId(){return strProductId;}
void CPersonalOrder::SetProductNum(int products){iProducts = products;}
int CPersonalOrder::GetProductNum(){return iProducts;}
string CPersonalOrder::ToStr()
{
ostringstream oss; oss << iProducts;
return ("PersonalOrder's Order\nCustomer : " + strCustomer + ", Name : " +
pProduct->GetName() + ", Id : " + pProduct->GetId() + ", Num : " + oss.str() + ".");
}
CAbsOrder* CPersonalOrder::Clone()
{
CAbsOrder* pOrder = new CPersonalOrder();
pOrder->SetName(strCustomer);
pOrder->SetProduct(pProduct->Clone());//深度克隆
pOrder->SetProductNum(iProducts);
return pOrder;
}
CEnterpriseOrder::CEnterpriseOrder(){pProduct = NULL; iProducts = 0;}
string CEnterpriseOrder::ToStr()
{
ostringstream oss; oss << iProducts;
return ("EnterpriseOrder's Order\nEnterprise : " + strEnterprise + ", Name : " +
pProduct->GetName() + ", Id : " + pProduct->GetId() + ", Num : " + oss.str() + ".\n");
}
void CEnterpriseOrder::SetName(string enterprise){strEnterprise = enterprise;}
string CEnterpriseOrder::GetName(){return strEnterprise;}
void CEnterpriseOrder::SetProduct(CProductPrototype* product){pProduct = product;}
CProductPrototype* CEnterpriseOrder::GetProduct(){return pProduct;}
void CEnterpriseOrder::SetProductId(string productid){strProductId = productid;}
string CEnterpriseOrder::GetProductId(){return strProductId;}
void CEnterpriseOrder::SetProductNum(int products){iProducts = products;}
int CEnterpriseOrder::GetProductNum(){return iProducts;}
CAbsOrder* CEnterpriseOrder::Clone()
{
CAbsOrder* pOrder = new CEnterpriseOrder();
pOrder->SetName(strEnterprise);
pOrder->SetProduct(pProduct->Clone());
pOrder->SetProductNum(iProducts);
return pOrder;
}
//*********************************订单拆分过程********************
//处理订单
//saveOrder传入的是订单接口类型的对象实例,这里只知道
//订单接口的类型,并不知道其具体类型是个人订单还是企业订单
void OrderDispatch(CAbsOrder* pOrgOrder)
{
//1:判断当前的预定产品数量是否大于1000
int iNew = 0;
while(pOrgOrder->GetProductNum() > 1000){
//2.如果大于,还需要继续拆分
//2.1 再新建一份订单,跟传入的订单除了数量不一样外,
//其他都相同
//如果不采用克隆的方式,下面这行是不知道如何new一个
//对象的,因为order只是个接口,不能直接实例化。而
//Clone的作用在运行时order这个具体的对象是知道自己的类型的
//所以可以通过自身克隆出一个新的对象。
CAbsOrder* pNewOrder = pOrgOrder->Clone();
//然后进行赋值,产品数量为1000
pNewOrder->SetProductNum(1000);
//2.2 原来的订单保留,把数量减少1000
pOrgOrder->SetProductNum(pOrgOrder->GetProductNum()-1000);
//然后是业务处理功能,省略了,打印输出看一下
cout << "Split Order" << ++iNew << " : " << pNewOrder->ToStr() << endl;
delete pNewOrder;
}
}
//客户端
void main()
{
//创建订单对象,这里为了演示简单,直接new了
CAbsOrder* pOrgOrder = new CPersonalOrder();
CProductPrototype* pProduct = new CProductPrototype();
//设置产品
pProduct->SetName("Product"); pProduct->SetId("9527");
//设置订单数据
pOrgOrder->SetName("Tony");
pOrgOrder->SetProductNum(2925);
pOrgOrder->SetProduct(pProduct);
OrderDispatch(pOrgOrder);//调用业务来保存订单对象
cout << "Now OrgOrder" << " : " << pOrgOrder->ToStr() << endl;
delete pOrgOrder;
}