栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++设计模式-创建型设计模式:原型模式

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++设计模式-创建型设计模式:原型模式

目录

原型模式的场景、设计思路、功能

场景

如何设计?

功能:通过克隆来创建新的对象实例


原型模式的场景、设计思路、功能

场景

如何设计?

老套路,不使用设计模式来设计:

  • 抽象出OrderApi 去处理 HomeOrder 和 AboardOrder,然后调用OrderBussiness来处理
  • 已经有了某个对象实例后,如何快速简单地创建出更多这种对象?
#include 
#include 	
#include 
using namespace std;
//转换为string
template
string iToStr(T& 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() {
		return m_orderProductNum;
	}
	void setOrderProductNum(int num) {
		m_orderProductNum = num;
	}
	string getOrderContent() {
		return "本次订单客户:" + m_strCustomerName +
			" 订单数量:" + iToStr( m_orderProductNum )+
			" 订单ID:" + m_strProductId ;
	}
	void setCunstomerName(string strCustomerName) {
		m_strCustomerName = strCustomerName;
	}
	string getCumstomerName() {
		return m_strCustomerName;
	}

	void setProductId(string strProductId) {
		m_strProductId = strProductId;
	}
	string getProductId() {
		return m_strProductId;
	}
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};
//国外订单
class AboardOrder :public OrderApi {
public:
	int getOrderProductNum() {
		return m_orderProductNum;
	}
	void setOrderProductNum(int num) {
		m_orderProductNum = num;
	}
	string getOrderContent() {
		return "本次订单客户:" + m_strCustomerName +
			" 订单数量:" + iToStr(m_orderProductNum) +
			" 订单ID:" + m_strProductId;
	}
	void setCunstomerName(string strCustomerName) {
		m_strCustomerName = strCustomerName;
	}
	string getCumstomerName() {
		return m_strCustomerName;
	}

	void setProductId(string strProductId) {
		m_strProductId = strProductId;
	}
	string getProductId() {
		return m_strProductId;
	}
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};
//订单业务
class OrderBusiness {
public:
	void saveOrder(OrderApi* pOrder) {
		//判断工件数量是否超过200
		while (pOrder->getOrderProductNum() > 200) {
			//新建一个订单
			//问题来了,这时候根本不知道传入的是国内还是国外地订单
			OrderApi* pNewOrder = nullptr;
			if (dynamic_cast(pOrder) != nullptr) {
				//创建一个新对象
				HomeOrder* p2 = new HomeOrder;
				//赋值对象
				HomeOrder* p1 = static_cast(pOrder);
				p2->setOrderProductNum(200);
				p2->setCunstomerName(p1->getCumstomerName());
				p2->setProductId(p1->getProductId());
				pNewOrder = p2;
			}

			//海外订单
			if (dynamic_cast(pOrder) != nullptr) {
				//创建一个新对象
				AboardOrder* p2 = new AboardOrder;
				//赋值对象
				AboardOrder* p1 = static_cast(pOrder);
				p2->setOrderProductNum(200);
				p2->setCunstomerName(p1->getCumstomerName());
				p2->setProductId(p1->getProductId());
				pNewOrder = p2;
			}
			//原来的订单,还是保留,但数量要减少200
			pOrder->setOrderProductNum(pOrder->getOrderProductNum() - 200);
			cout << "新订单:" << pNewOrder->getOrderContent() << endl;
		}
		//不超过200个
		cout << " 最终订单: " << pOrder->getOrderContent() << endl;
	}
};

int main() {
	HomeOrder* pHome = new HomeOrder;
	pHome->setOrderProductNum(512);
	pHome->setCunstomerName("yxh");
	pHome->setProductId("C++ pattern");
	OrderBusiness* pOb = new OrderBusiness;
	pOb->saveOrder(pHome);
	return 0;
}

可以运行,但有什么问题?

同样的,在Builder模式中,重构前有大量重复冗余地代码,在这里也一样,有重复冗余的if 语句,

这里就应该重构。

DRY原则:Don't Repeat yourself!

重构:

#include 
#include 	
#include 
using namespace std;
//转换为string
template
string iToStr(T& 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() {
		return m_orderProductNum;
	}
	void setOrderProductNum(int num) {
		m_orderProductNum = num;
	}
	string getOrderContent() {
		return "本次订单客户:" + m_strCustomerName +
			" 订单数量:" + iToStr(m_orderProductNum) +
			" 订单ID:" + m_strProductId;
	}
	void setCunstomerName(string strCustomerName) {
		m_strCustomerName = strCustomerName;
	}
	string getCumstomerName() {
		return m_strCustomerName;
	}

	void setProductId(string strProductId) {
		m_strProductId = strProductId;
	}
	string getProductId() {
		return m_strProductId;
	}
	//重构
	OrderApi* cloneOrder() {
		HomeOrder* pHomeOrder = new HomeOrder;
		pHomeOrder->setCunstomerName(m_strCustomerName);
		pHomeOrder->setProductId(m_strProductId);
		pHomeOrder->setOrderProductNum(m_orderProductNum);
		return pHomeOrder;
	}
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};
//国外订单
class AboardOrder :public OrderApi {
public:
	int getOrderProductNum() {
		return m_orderProductNum;
	}
	void setOrderProductNum(int num) {
		m_orderProductNum = num;
	}
	string getOrderContent() {
		return "本次订单客户:" + m_strCustomerName +
			" 订单数量:" + iToStr(m_orderProductNum) +
			" 订单ID:" + m_strProductId;
	}
	void setCunstomerName(string strCustomerName) {
		m_strCustomerName = strCustomerName;
	}
	string getCumstomerName() {
		return m_strCustomerName;
	}

	void setProductId(string strProductId) {
		m_strProductId = strProductId;
	}
	string getProductId() {
		return m_strProductId;
	}

	//重构
	OrderApi* cloneOrder() {
		AboardOrder* pAboardOrder = new AboardOrder;
		pAboardOrder->setCunstomerName(m_strCustomerName);
		pAboardOrder->setProductId(m_strProductId);
		pAboardOrder->setOrderProductNum(m_orderProductNum);
		return pAboardOrder;
	}
private:
	string m_strCustomerName;
	string m_strProductId;
	int m_orderProductNum;
};

//订单业务
class OrderBusiness {
public:
	void saveOrder(OrderApi* pOrder) {
		//判断工件数量是否超过200
		while (pOrder->getOrderProductNum() > 200) {
			//新建一个订单
			//重构
			OrderApi* pNewOrder = pOrder->cloneOrder();
			pNewOrder->setOrderProductNum(200);

			//原来的订单,还是保留,但数量要减少200
			pOrder->setOrderProductNum(pOrder->getOrderProductNum() - 200);
			cout << "新订单:" << pNewOrder->getOrderContent() << endl;
		}
		//不超过200个
		cout << " 最终订单: " << pOrder->getOrderContent() << endl;
	}
};

int main() {
	HomeOrder* pHome = new HomeOrder;
	pHome->setOrderProductNum(512);
	pHome->setCunstomerName("yxh");
	pHome->setProductId("C++ pattern");
	OrderBusiness* pOb = new OrderBusiness;
	pOb->saveOrder(pHome);
	return 0;
}

结果是一样的。

其核心部分在于,将之前的:

			OrderApi* pNewOrder = nullptr;
			if (dynamic_cast(pOrder) != nullptr) {
				//创建一个新对象
				HomeOrder* p2 = new HomeOrder;
				//赋值对象
				HomeOrder* p1 = static_cast(pOrder);
				p2->setOrderProductNum(200);
				p2->setCunstomerName(p1->getCumstomerName());
				p2->setProductId(p1->getProductId());
				pNewOrder = p2;
			}

			//海外订单
			if (dynamic_cast(pOrder) != nullptr) {
				//创建一个新对象
				AboardOrder* p2 = new AboardOrder;
				//赋值对象
				AboardOrder* p1 = static_cast(pOrder);
				p2->setOrderProductNum(200);
				p2->setCunstomerName(p1->getCumstomerName());
				p2->setProductId(p1->getProductId());
				pNewOrder = p2;
			}

重构为两个部分:

	//重构
	OrderApi* cloneOrder() {
		HomeOrder* pHomeOrder = new HomeOrder;
		pHomeOrder->setCunstomerName(m_strCustomerName);
		pHomeOrder->setProductId(m_strProductId);
		pHomeOrder->setOrderProductNum(m_orderProductNum);
		return pHomeOrder;
	}
	//重构
	OrderApi* cloneOrder() {
		AboardOrder* pAboardOrder = new AboardOrder;
		pAboardOrder->setCunstomerName(m_strCustomerName);
		pAboardOrder->setProductId(m_strProductId);
		pAboardOrder->setOrderProductNum(m_orderProductNum);
		return pAboardOrder;
	}

功能:通过克隆来创建新的对象实例

为克隆出来的新的对象实例复制原型实例属性的值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1034646.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号