加入星計劃,您可以享受以下權益:

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

《大話設計模式》解讀06-原型模式

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

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

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

1 原型模式

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

原型模式的類圖如下:

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

2 實例

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

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

2.1 版本一:單一簡歷類

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

2.1.1 簡歷類

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

    簡歷類構造時傳入姓名作為參數(shù)調用設置個人信息方法SetPersonalInfo,可設置性別和年齡調用設置工作經歷方法SetWorkExperience,可設置工作時間與工作的公司調用顯示方法Display,可顯示簡歷的完整內容
// 簡歷類
class Resume
{
public:
    Resume(std::string name)
    {
        m_name = name;
    }
    
    // 設置個人信息
    void SetPersonalInfo(std::string sex, int age)
    {
        m_sex  = sex;
        m_iAge = age;
    }    
    
    // 設置工作經歷
    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("工作經歷:%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ù)

首先,實例化三份簡歷,并分別設置具體的內容,

然后,就可以調用展示接口來顯示出來了。

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 版本二:原型模式

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

另外,工作經歷設計為一個單獨類,通過組合方式,作為簡歷類的一部分。

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

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

2.2.1 工作經歷類、簡歷原型類與簡歷類

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

    工作經歷類:作為簡歷的一部分,實現(xiàn)工作時間與對應的工作公司的信息,并提供克隆接口簡歷原型類:一個抽象類,定義了簡歷所具有的基本信息及接口,并提供克隆接口,實現(xiàn)簡歷克隆簡歷類:繼承簡歷原型類,并實現(xiàn)簡歷原型中定義的方法
// 工作經歷
class WorkExperience
{
public:
    WorkExperience() {}
    ~WorkExperience(){}
    
    WorkExperience(WorkExperience *work)
    {
        this->m_timeArea = work->m_timeArea;
        this->m_company  = work->m_company;
    }
    
    // 設置/獲取工作時間
    void SetWorkTiemArea(std::string timeArea)
    {
        m_timeArea = timeArea;
    }  
    
    std::string GetWorkTiemArea()
    {
        return m_timeArea;
    }
    
    // 設置/獲取工作公司
    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;
        }
    }
    
    // 設置個人信息
    void SetPersonalInfo(std::string sex, int age)
    {
        m_sex  = sex;
        m_iAge = age;
    }   
     
    // 設置工作經歷
    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("工作經歷:%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,并設置一些基礎信息。

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

最后,調用顯示接口顯示簡歷的內容。

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

代碼運行效果如下:

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

總結

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

文章推薦

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

《大話設計模式》解讀02-策略模式

《大話設計模式》解讀03-裝飾模式

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

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
TJA1055T/1J 1 NXP Semiconductors TJA1055 - Enhanced fault-tolerant CAN transceiver SOIC 14-Pin
$1.72 查看
R38-32.768-12.5 1 Raltron Electronics Corporation Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom, HALOGEN FREE, ROHS AND REACH COMPLIANT PACKAGE-2
$0.06 查看
SN74LV244APWG4 1 Texas Instruments Eight-channel 2-V to 5.5-V buffers with tri-state outputs 20-TSSOP -40 to 125

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看

相關推薦

電子產業(yè)圖譜

控制科學與工程碩士,日常分享單片機、嵌入式、C/C++、Linux等學習經驗干貨~