第9章原型模式

一 概念与说明

  • 原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  • 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

二 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;
}

猜你喜欢

转载自www.cnblogs.com/Manual-Linux/p/11125128.html