目录
原型模式的场景、设计思路、功能
场景
如何设计?
功能:通过克隆来创建新的对象实例
原型模式的场景、设计思路、功能
场景
如何设计?
老套路,不使用设计模式来设计:
- 抽象出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;
}
功能:通过克隆来创建新的对象实例
为克隆出来的新的对象实例复制原型实例属性的值



