Creational.Prototype(创建型模式—原型模式)

标签: DesignPattern(程序设计的指导思想)
21人阅读 评论(0) 收藏 举报
分类:

思考原型模式

  ①原型模型的本质克隆生成对象

  ②原型模式可以用来解决“只知接口而不知实现的问题”,出现一种“接口造接口”的假象。

  ③原型模式的重心还是在创建新的对象实例。至于创建出来的对象,其属性的值是否一定要和原型对象完全一样,这并没有强制规定,但一般会拷贝成一样的。

  ④通过克隆出来实例是原型实例是两个完全独立的实例,他们之间没有关联。

【编程实验】订单拆分处理

//创建型模式:原型模式//订单处理:
/*
    功能需求:因每个工作小组的处理能力上限是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;

}

查看评论

23种设计模式----创建型模式(工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式)

1.单例模式  单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自己实例化并向整个系统提供这个实例。   通用类图如下:      通用代码如下:public cl...
  • oChangWen
  • oChangWen
  • 2017-06-17 21:37:07
  • 709

GoF23种设计模式之创建型模式之原型模式

一、概述         用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 二、适用性 1.当一个系统应该独立于它的产品创建、构成和表示的时候。 2.当要实例化的类是在运行时刻指定的时...
  • leverage_1229
  • leverage_1229
  • 2013-05-30 12:59:12
  • 1658

对象创建型模式之原型模式

    应用场景:Ctrl+C Ctrl+V,Struts中保证线程的安全性,Action 对象的创建使用了原型模式,访问一个已经存在Action对象时将通过克隆的方式创建出一个新的对象,从而保证其中...
  • qq_33977775
  • qq_33977775
  • 2018-03-06 10:54:10
  • 53

六种创建型设计模式的比较和总结

一、描述 创建型设计模式包括如下几个:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、创建者模式(Bui...
  • tongyuehong
  • tongyuehong
  • 2015-05-02 15:46:41
  • 1537

C#面向对象设计模式纵横谈(

  • 2011年03月29日 08:36
  • 141KB
  • 下载

C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式)

  • 2009年05月25日 09:38
  • 8.38MB
  • 下载

C#面向对象设计模式纵横谈(5)

  • 2008年05月10日 22:55
  • 8.38MB
  • 下载

C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式) (Level 300)

  • 2008年09月13日 15:53
  • 8.26MB
  • 下载

创建型模式——原型模式

1、什么是原型模式 原型模式就是将一个已有的实例对象,将其复制出一个一模一样的实例对象出来,也就是克隆,原型模式算是设计模式中最简单的一个。它的核心就是类图中的Prototype类,实现原型模式非常...
  • u014174811
  • u014174811
  • 2015-11-16 09:20:28
  • 496

创建型模式之原型模式

原型模式 概述:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 适用性:     1.当一个系统应该独立于它的产品创建、构成和表示时。     2.当要实...
  • gxiangzi
  • gxiangzi
  • 2010-12-08 22:29:00
  • 403
    个人资料
    等级:
    访问量: 1478
    积分: 880
    排名: 6万+
    文章存档