1. 程式人生 > >05:原型模式——C++實現

05:原型模式——C++實現

目錄

一、介紹

二、應用場景

三、要點

四、樣例

五、優缺點


一、介紹

    原型模式(Prototype Pattern是用於建立重複的物件,同時又能保證效能。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

這種模式是實現了一個原型介面,該介面用於建立當前物件的克隆。當直接建立物件的代價比較大時,則採用這種模式。例如,一個物件需要在一個高代價的資料庫操作之後被建立。我們可以快取該物件,在下一個請求時返回它的克隆,在需要的時候更新資料庫,以此來減少資料庫呼叫。

 

二、應用場景

1、資源優化場景。

2、類初始化需要消化非常多的資源,這個資源包括資料、硬體資源等。

3、效能和安全要求的場景。

4、通過 new 產生一個物件需要非常繁瑣的資料準備或訪問許可權,則可以使用原型模式。

5、一個物件多個修改者的場景。

6、一個物件需要提供給其他物件訪問,而且各個呼叫者可能都需要修改其值時,可以考慮使用原型模式拷貝多個物件供呼叫者使用。

7、在實際專案中,原型模式很少單獨出現,一般是和工廠方法模式一起出現,通過 clone 的方法建立一個物件,然後由工廠方法提供給呼叫者。原型模式已經與 Java 融為渾然一體,大家可以隨手拿來使用。

 

 

三、要點

    與通過對一個類進行例項化來構造新物件不同的是,原型模式是通過拷貝一個現有物件生成新物件的。淺拷貝實現 Cloneable,重寫,深拷貝是通過實現 Serializable 讀取二進位制流。

 

四、樣例

    原型模式提供了自我複製功能,就像孫悟空拔出一根猴毛,吹口氣幻化成多個猴子一樣。

1、建立抽象原型

#// prototype.h
#ifndef PROTOTYPE_H
#define PROTOTYPE_H

class Monkey
{
public:
	Monkey(){}
	virtual ~Monkey(){}
	virtual Monkey* Clone() = 0;        // 克隆
	virtual void Play() = 0;        // 玩耍
};
#endif

2、建立具體原型

// concrete_prototype.h
#ifndef CONCRETE_PROTOTYPE_H
#define CONCRETE_PROTOTYPE_H

#include "prototype.h"
#include <iostream>
#include <string>

using namespace std;

class SunWuKong :public Monkey
{
public:
	SunWuKong(string name){ m_strName = name; }
	~SunWuKong(){}

	// 拷貝建構函式
	SunWuKong(const SunWuKong &nother)
	{
		m_strName = other.m_strName;
	}

	Monkey* Clone()
	{
		// 呼叫拷貝建構函式
		return new SunWuKong(*thhis);
	}

	void Play()
	{
		cout << m_strName << "play Golden-Hoop-Stick" << endl;
	}

private:
	string m_strName;
};

#endif

3、建立客戶端

// main.cpp
#include "concrete_prototype.h"

#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){ delete(p); (p) = NULL; } }
#endif

int main()
{
	Monkey *pSWK = new SunWuKong("Qi Tian Da Sheng");

	Monkey *pSWK1 = pSWK->Clone();
	Monkey *pSWK2 = pSWK->Clone();

	pSWK1->Play();
	pSWK2->Play();

	SAFE_DELETE(pSWK1);
	SAFE_DELETE(pSWK2);
	SAFE_DELETE(pSWK);

	getchar();
	return 0;
}

輸出:

Qi Tian Da Sheng play Golden - Hoop - Stick
Qi Tian Da Sheng play Golden - Hoop - Stick

 

五、優缺點

優點: 1、效能提高。 2、逃避建構函式的約束。

缺點: 1、配備克隆方法需要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不一定很容易,特別當一個類引用不支援序列化的間接物件,或者引用含有迴圈結構的時候。 2、必須實現 Cloneable 介面。