一、概述
1、工作原理:將一個原型對象傳給要發動創建的對象(即客戶端對象),這個要發動創建的對象通過請求原型對象復制自己來實現創建過程
2、通過克隆方法所創建的對象是全新的對象,它們在內存中擁有新的地址,每一個克隆對象都是獨立的
3、核心思想:是通過復制現有對象的原型來創建對象,而不是通過實例化來創建對象。
二、原型模式的結構
原型模式包含以下3個角色
(1)Prototype(抽象原型類)
(2)ConcretePrototype(具體原型類)
(3)Client(客戶類)
三、淺克隆與深克隆
1、淺克隆:當原型對象被復制時,只復制它本身和其中包含的值類型的成員變量,而引用類型的成員變量并沒有復制
?2、深克隆:除了對象本身被復制外,對象所包含的所有成員變量也將被復制
四、模式優點?
1、簡化對象的創建過程,通過復制一個已有實例可以提高新實例的創建效率
2、擴展性較好
3、提供了簡化的創建結構,原型模式中產品的復制是通過封裝在原型類中的克隆方法實現的,無須專門的工廠類來創建產品
五、模式缺點
1、需要為每一個類配備一個克隆方法,而且該克隆方法位于一個類的內部,當對已有的類進行改造時,需要修改源代碼,違背了開閉原則
2、在實現深克隆時需要編寫較為復雜的代碼,而且當對象之間存在多重嵌套引用時,為了實現深克隆,每一層對象對應的類都必須支持深克隆,實現起來可能會比較麻煩
六、模式適用環境
1、創建對象成本較大,新對象可以通過復制已有對象來獲得,如果是相似對象,則可以對其成員變量稍作修改
2、系統要保存對象的狀態,而對象的狀態變化很小
3、需要避免使用分層次的工廠類來創建分層次的對象,并且類的實例對象只有一個或很少幾個組合狀態,通過復制原型對象得到新實列可能比使用構造函數創建一個新實例更加方便
七、原型模式示例代碼
#include <iostream>
#include <map>
using namespace std;
class Prototype
{
public:virtual Prototype* clone() const = 0;virtual void showInfo() const = 0;
};class Car : public Prototype
{
public:Car(const string& make, const string& model, int year): m_make(make), m_model(model), m_year(year){}void showInfo() const override{cout << m_year << " " << m_make << " " << m_model << endl;}protected:Prototype* clone() const override{return new Car(m_make, m_model, m_year);}private:string m_make;string m_model;int m_year;
};class PrototypeFactory
{
public:Prototype* getPrototype(const string& type){return m_prototypes[type]->clone();}void addPrototype(const string& type, Prototype* prototype){m_prototypes[type] = prototype;}
private:map<string, Prototype*> m_prototypes;
};int main()
{PrototypeFactory factory;Car* carPrototype = new Car("Honda", "Accord", 2024);factory.addPrototype("Car", carPrototype);Prototype* cloneCar = factory.getPrototype("Car");carPrototype->showInfo();cloneCar->showInfo();return 0;
}