加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 1 原型模式
    • 2 實例
    • 總結(jié)
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

《大話設(shè)計模式》解讀06-原型模式

08/20 10:15
932
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

上篇文章,介紹了《大話設(shè)計模式》的第8章——工廠方法。

本篇,來介紹《大話設(shè)計模式》的第9章——原型模式。并通過C++代碼實現(xiàn)實例代碼的功能。

1 原型模式

原型模式(Prototype):用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。

原型模式的類圖如下:

    Client:讓一個原型克隆自身從而創(chuàng)建一個新的對象Prototype:原型類,聲明一個克隆自身的接口ConcreatePrototype:具體原型類,實現(xiàn)一個克隆自身的操作

2 實例

背景:書中小故事,小菜要去找工作,準(zhǔn)備了很厚一疊簡歷,大鳥在感慨他那時找工作的時候,都是手寫簡歷,現(xiàn)在印簡歷就像印草紙一樣,由此聯(lián)想到代碼中的復(fù)制粘貼。

題目:用代碼的形式來實現(xiàn)簡歷類的功能,要求必須要有姓名,可以設(shè)置性別和年齡,可以設(shè)置工作經(jīng)歷,最終需要寫三份簡歷。

2.1 版本一:單一簡歷類

版本一的實現(xiàn)比較簡單,僅設(shè)計一個簡歷類。

2.1.1 簡歷類

簡歷類的實現(xiàn)如下:

    簡歷類構(gòu)造時傳入姓名作為參數(shù)調(diào)用設(shè)置個人信息方法SetPersonalInfo,可設(shè)置性別和年齡調(diào)用設(shè)置工作經(jīng)歷方法SetWorkExperience,可設(shè)置工作時間與工作的公司調(diào)用顯示方法Display,可顯示簡歷的完整內(nèi)容
// 簡歷類
class Resume
{
public:
    Resume(std::string name)
    {
        m_name = name;
    }
    
    // 設(shè)置個人信息
    void SetPersonalInfo(std::string sex, int age)
    {
        m_sex  = sex;
        m_iAge = age;
    }    
    
    // 設(shè)置工作經(jīng)歷
    void SetWorkExperience(std::string timeArea, std::string company)
    {
        m_timeArea = timeArea;
        m_company  = company;
    }  
    
    // 顯示
    void Display()
    {
        printf("%s %s %dn", m_name.c_str(), m_sex.c_str(), m_iAge);
        printf("工作經(jīng)歷:%s %sn", m_timeArea.c_str(), m_company.c_str());
    }

private:
    std::string m_name;
    std::string m_sex;
    int         m_iAge;
    std::string m_timeArea;
    std::string m_company;
};

2.1.2 主函數(shù)

首先,實例化三份簡歷,并分別設(shè)置具體的內(nèi)容,

然后,就可以調(diào)用展示接口來顯示出來了。

int main()
{
    // 實例化三份簡歷
    Resume a = Resume("大鳥");
    a.SetPersonalInfo("男", 29);
    a.SetWorkExperience("2018-2020", "XX公司");
    
    Resume b = Resume("大鳥");
    b.SetPersonalInfo("男", 29);
    b.SetWorkExperience("2018-2020", "XX公司");
    
    Resume c = Resume("大鳥");
    c.SetPersonalInfo("男", 29);
    c.SetWorkExperience("2018-2020", "XX公司");
    
    // 顯示出來
    a.Display();
    b.Display();
    c.Display();
    
    return 0;
}

代碼運行效果如下:

下面來看版本二。

2.2 版本二:原型模式

版本二,使用原型模型,設(shè)計了一個簡歷原型類,定義了簡歷所具有的基本信息及接口,簡歷類則繼承簡歷原型類,

另外,工作經(jīng)歷設(shè)計為一個單獨類,通過組合方式,作為簡歷類的一部分。

注1:書中代碼使用的C#,C#中有MemberwiseClone方法進行拷貝,而C++中無此方法,因此需要重新實現(xiàn)一個Clone方法。

注2:對對象進行拷貝時,會涉及到淺拷貝與深拷貝的概念,而MemberwiseClone方法對于引用類型的對象,復(fù)制的是引用而不是復(fù)制對象,這樣就會帶來修改了復(fù)制后的對象,原對象也會被修改。因此,書中例子講工作經(jīng)歷單獨拎出來作為一個類,拷貝簡歷時,簡歷中的工作經(jīng)歷將為引用類型,以此來對比演示淺拷貝帶來的影響。解決方法就是改為深拷貝,在工作經(jīng)歷類的內(nèi)部也實現(xiàn)一個Clone方法。

2.2.1 工作經(jīng)歷類、簡歷原型類與簡歷類

這里需要實現(xiàn)三個類:

    工作經(jīng)歷類:作為簡歷的一部分,實現(xiàn)工作時間與對應(yīng)的工作公司的信息,并提供克隆接口簡歷原型類:一個抽象類,定義了簡歷所具有的基本信息及接口,并提供克隆接口,實現(xiàn)簡歷克隆簡歷類:繼承簡歷原型類,并實現(xiàn)簡歷原型中定義的方法
// 工作經(jīng)歷
class WorkExperience
{
public:
    WorkExperience() {}
    ~WorkExperience(){}
    
    WorkExperience(WorkExperience *work)
    {
        this->m_timeArea = work->m_timeArea;
        this->m_company  = work->m_company;
    }
    
    // 設(shè)置/獲取工作時間
    void SetWorkTiemArea(std::string timeArea)
    {
        m_timeArea = timeArea;
    }  
    
    std::string GetWorkTiemArea()
    {
        return m_timeArea;
    }
    
    // 設(shè)置/獲取工作公司
    void SetWorkCompany(std::string company)
    {
        m_company  = company;
    }
    
    std::string GetWorkCompany()
    {
        return m_company;
    } 
    
    // Clone
    WorkExperience *Clone()
    {
        return new WorkExperience(this);
    } 
    
private:
    std::string m_timeArea;
    std::string m_company;
};

// 簡歷原型類
class Prototype
{
public:
    virtual void SetPersonalInfo(std::string sex, int age) = 0;
    virtual void Display() = 0;
    virtual Prototype *Clone() = 0;
    
protected:
    std::string m_name;
    std::string m_sex;
    int         m_iAge;    
    std::string m_timeArea;
    std::string m_company;
};

// 簡歷類
class Resume : public Prototype
{
public:
    Resume(std::string name)
    {
        m_name  = name;
        m_pWork = new WorkExperience();
    }
    
    ~Resume()
    {
        if (m_pWork)
        {
            delete m_pWork;
        }
    }
    
    // 設(shè)置個人信息
    void SetPersonalInfo(std::string sex, int age)
    {
        m_sex  = sex;
        m_iAge = age;
    }   
     
    // 設(shè)置工作經(jīng)歷
    void SetWorkExperience(std::string timeArea, std::string company)
    {
        m_pWork->SetWorkTiemArea(timeArea);
        m_pWork->SetWorkCompany(company);
    }  
    
    // 顯示
    void Display()
    {
        printf("%s %s %dn", m_name.c_str(), m_sex.c_str(), m_iAge);
        printf("工作經(jīng)歷:%s %sn", m_pWork->GetWorkTiemArea().c_str(), m_pWork->GetWorkCompany().c_str());
    }
    
    Resume *Clone()
    {
        Resume *pClone = new Resume(m_name);
        pClone->SetPersonalInfo(m_sex, m_iAge);
        return pClone;
    }
    
private:
    WorkExperience *m_pWork;
};

2.2.2 主函數(shù)

首先,實例化了一個簡歷A,并設(shè)置一些基礎(chǔ)信息。

然后,通過克隆的方式,產(chǎn)生簡歷B與簡歷C,并對簡歷B與簡歷C進行個性化修改。

最后,調(diào)用顯示接口顯示簡歷的內(nèi)容。

int main()
{
    // 實例化三份簡歷
    Resume a = Resume("大鳥");
    a.SetPersonalInfo("男", 29);
    a.SetWorkExperience("2018-2020", "XX公司");
    
    Resume *b = a.Clone();
    b->SetWorkExperience("2018-2021", "YY公司");
    
    Resume *c = a.Clone();
    c->SetPersonalInfo("男", 24);
    c->SetWorkExperience("2018-2022", "ZZ公司");
    
    // 顯示出來
    a.Display();
    b->Display();
    c->Display();
    
    delete b;
    delete c;
      
    return 0;
}

代碼運行效果如下:

原型模式的主要特點在于設(shè)計了一個克隆方法,通過克隆,將當(dāng)前對象的當(dāng)前狀態(tài)做一個拷貝,形成一個新的對象,注意體會這里的“當(dāng)前狀態(tài)”,它不是初始狀態(tài),而是在程序運行到某一時刻時其內(nèi)部屬性的最新狀態(tài)。

總結(jié)

本篇介紹了設(shè)計模式中的原型模式,并通過簡歷編寫的實例,使用C++編程,來演示原型模式的使用。

文章推薦

《大話設(shè)計模式》解讀01-簡單工廠模式

《大話設(shè)計模式》解讀02-策略模式

《大話設(shè)計模式》解讀03-裝飾模式

《大話設(shè)計模式》解讀05-工廠方法

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
XRCGB25M000F3A00R0 1 Murata Manufacturing Co Ltd Parallel - Fundamental Quartz Crystal, 25MHz Nom, ROHS AND REACH COMPLIANT, SMALL, SMD, 3 PIN

ECAD模型

下載ECAD模型
$0.34 查看
M25P05-AVMN6P 1 Rochester Electronics LLC 64KX8 FLASH 2.7V PROM, PDSO8, 0.150 INCH, ROHS COMPLIANT, PLASTIC, SOP-8
$0.79 查看
S29GL256P10FFI020 1 AMD Flash, 16MX16, 100ns, PBGA64,
$9.29 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

控制科學(xué)與工程碩士,日常分享單片機、嵌入式、C/C++、Linux等學(xué)習(xí)經(jīng)驗干貨~