1. 程式人生 > >設計模式之享元模式(C++)

設計模式之享元模式(C++)

設計模式之享元模式

享元模式,運用共享技術有效地支援大量細粒度的物件。面向物件技術可以很好地解決一些靈活性或擴充套件性問題,但在很多情況下需要在系統中增加類和物件的個數。當物件數量太多時,將導致執行代價過高,帶來效能下降等問題。享元模式正式為了解決這依賴問題而誕生的。享元模式通過共享技術實現相同或相似物件的重用,示意圖如下(我們可以公用一個Hello world物件,其中字串“Hello world”為內部狀態,可共享:字型顏色為外部狀態,不可共享,由客戶端設定)該部分這個bolg寫的很好享元模式示意圖 在享元模式中可以共享的相同內容成為內部狀態,而那些需要外部環境來設定的不能共享的內容稱為外部狀態,其中外部狀態和內部狀態是相互獨立的,外部狀態的變化不會引起內部狀態的變化。由於區分了內部狀態和外部狀態,因此可以通過設定不同的外部狀態使得相同的物件可以具有一些不同的特徵,而相同的內部狀態是可以共享的。也就是說,享元模式的本質是分離與共享:分離變與不變,並且共享不變。把一個獨享的狀態分為內部狀態和外部狀態,內部狀態即是不變的,外部狀態時變化的;然後通過共享不變的部分,達到減少物件數量並節約記憶體的目的。

在享元模式中通常會出現工廠模式,需要建立一個享元工廠來負責維護一個享元池(用於儲存具有相同內部狀態的享元物件)。在享元模式中,共享的是享元物件的內部狀態,外部狀態需要通過環境來設定。在實際使用中,能夠共享的內部狀態是有限的,因此享元物件一般都設計為較小的物件,它所包含的內部狀態較少,這種物件也成為細粒度物件。比如在C++中的常量字串。python中的小整數,應該都是這種模式。其UML圖如下: 享元模式UML圖 示例程式碼如下:

// FlyweightModel.h檔案
#pragma once
#include <iostream>
#include <map>
#include <utility>
class Flyweight { public: virtual void Operation(int n) = 0; }; class ConcreteFlyweight_0 : public Flyweight { public: void Operation(int n) { std::cout << "ConcreteFlyweight_0:" << n << std::endl; } }; class ConcreteFlyweight_1 : public Flyweight { public: void Operation(int
n) { std::cout << "ConcreteFlyweight_1:" << n << std::endl; } }; class ConcreteFlyweight_2 : public Flyweight { public: void Operation(int n) { std::cout << "ConcreteFlyweight_2:" << n << std::endl; } }; // 享元工廠 class FlyweightFactory { private: std::map<int, Flyweight *> m_map; public: FlyweightFactory() { m_map.insert(std::pair<int, Flyweight *>(0, new ConcreteFlyweight_0())); m_map.insert(std::pair<int, Flyweight *>(1, new ConcreteFlyweight_1())); m_map.insert(std::pair<int, Flyweight *>(2, new ConcreteFlyweight_2())); } ~FlyweightFactory() { for (auto it = m_map.begin(); it != m_map.end(); it++) { delete it->second; } m_map.clear(); } Flyweight * getFlyweight(int n) { return m_map[n]; } };

測試程式碼如下:

#include <iostream>
#include "FlyweightModel.h"

int main()
{
	using namespace std;
	// 享元模式
	int externState = 0;
	FlyweightFactory * p = new FlyweightFactory();

	Flyweight * f0 = p->getFlyweight(0);
	f0->Operation(externState++);
	Flyweight * f1 = p->getFlyweight(1);
	f1->Operation(externState++);
	Flyweight * f2 = p->getFlyweight(2);
	f2->Operation(externState++);
	Flyweight * f3 = p->getFlyweight(0);
	f3->Operation(externState++);
	delete p;

	getchar();
	return 0;
}

測試結果如下圖: 在這裡插入圖片描述