天天看點

大話設計模式26----享元模式大話設計模式

大話設計模式

1 享元模式(Flyweight)結構圖

大話設計模式26----享元模式大話設計模式

2 對享元模式的一些解釋

概念:運用共享技術有效的支援大量細粒度的對象。【DP】

Flyweight類:是所有具體享元類的超類或接口,通過這個接口,Flyweight可以接受并作用于外部狀态。

class Flyweight
{
public:
	virtual void Operatiron(int extrinsicstate) = 0;
};
           

ConcreteFlyweight類:繼承Flyweight類或實作Flyweight接口,并為内部狀态增加存儲空間。

class ConcreteFlyweight :public Flyweight
{
public:
	void Operatiron(int extrinsicstate) override
	{
		cout << "具體Flyweight" << extrinsicstate << endl;
	}
};
           

UnsharedFlyweight類,指那些不需要共享的Flyweight子類,因為Flyweight接口共享成為可能,但它并不強制共享。

class UnsharedFlyweight :public Flyweight
{
public:
	void Operatiron(int extrinsicstate) override
	{
		cout << "不共享的具體Flyweight" << extrinsicstate << endl;
	}
};
           

FlyweightFactory類:一個共享工廠,用來建立并管理Flyweight對象。它主要用來確定合理的共享Flyweight,當使用者請求一個Flyweight時, FlyweightFactory對象提供一個已建立的執行個體或者建立一個。(不一定非得這樣,完全可以在需要時判斷是否為空來決定是否執行個體化)

class FlyweightFactory
{
private:
	Hashtable *flyweight = new Hashtable();

public:
	FlyweightFactory()
	{
		flyweight.Add("X", new ConcreteFlyweight());//用法錯誤,這裡隻是表示出這種形式
		flyweight.Add("Y", new ConcreteFlyweight());
		flyweight.Add("Z", new ConcreteFlyweight());
	}

	Flyweight *GetFlyweight(string key)
	{
		return (Flyweight *)flyweight[key];
	}
};
           

用戶端代碼:

int main()
{
	int extrinsicstate = 22;

	FlyweightFactory *f = new FlyweightFactory();

	Flyweight *fx = f->GetFlyweight("X");
	fx->Operatiron(--extrinsicstate);

	Flyweight *fy = f->GetFlyweight("Y");
	fx->Operatiron(--extrinsicstate);

	Flyweight *fz = f->GetFlyweight("Z");
	fx->Operatiron(--extrinsicstate);

	Flyweight *uf = new UnsharedFlyweight();
	uf->Operatiron(--extrinsicstate);

	return 0;
}
           

優點: 享元模式可以避免大量非常相似類的開銷。在程式設計中,有時需要生成大量細粒度的類執行個體來表示資料。如果能發現這些執行個體除了幾個參數外基本上都是相同的,有時就能夠大幅度的減少需要執行個體化的類的數量。如果能把那些參數移到類執行個體的外面,在方法調用時将它們傳遞進來,就可以通過共享大幅度地減少單個執行個體的數目。

也就是說,享元模式Flyweight執行時所需的狀态是有内部的也可能有外部的,内部狀态存儲于ConcreteFlyweight對象之中,而外部對象則應該考慮由用戶端對象存儲或計算,當調用Flyweight對象的操作時,将該狀态傳遞給它。

應用場景:

  • 如果一個應用程式使用了大量的對象,而大量的這些對象造成了很大的存儲開銷時就應該考慮使用;
  • 對象的大多數狀态可以是外部狀态,如果删除對象的外部狀态(用戶端代碼),那麼可以用相對較少的共享對象取代很多組對象,此時可以考慮使用享元模式。

3 C++源代碼實作

3.1  源代碼結構圖

大話設計模式26----享元模式大話設計模式

3.2 C++源代碼

User.h

#ifndef _USER_H_
#define _USER_H_

#include<string>
using std::string;

class User
{
private:
	string name;

public:
	User(string name)
	{
		this->name = name;
	}

	string getName()
	{
		return this->name;
	}
};

#endif
           

Flyweight.h(Website類)

#ifndef _FLYWEIGHT_H_
#define _FLYWEIGHT_H_

#include"User.h"
#include<string>
using std::string;

class Flyweight
{
public:
	virtual void Operation(User &user) = 0;
};	

class ConcreteFlyweight:public Flyweight
{
private:
	string name;

public:
	ConcreteFlyweight(string name);
	void Operation(User &user) override;
};

#endif
           

Flyweight.cpp(Website.cpp)

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

using std::cout;
using std::endl;

ConcreteFlyweight::ConcreteFlyweight(string name)
{
	this->name = name;
}

void ConcreteFlyweight::Operation(User &user)
{
	cout << "網站分類:\t" << name << ";\t使用者:" << user.getName() << endl;
}
           

FlyweightFactory.h(ConcreteWebsite.h)

#include<string>
#include<map>

using std::string;
using std::map;

#ifndef _FLYWEIGHT_FACTORY_H_
#define _FLYWEIGHT_FACTORY_H_

class Flyweight;

class FlyweightFactory
{
private:
	map<string, Flyweight *> *mmap = new map<string, Flyweight *>();

public:
	~FlyweightFactory();

	Flyweight *GetGlyweightGategory(string key);

	int GetFlywightCount();
};

#endif
           

FlyweightFactory.cpp(ConcreteFactory.cpp)

#include"Flyweight.h"
#include"FlyweightFactory.h"

FlyweightFactory::~FlyweightFactory()
{
	for (auto &m : (*mmap))
	{
		delete m.second;
	}

	delete mmap;
}


Flyweight *FlyweightFactory::GetGlyweightGategory(string key)
{
	for (const auto &m : (*mmap))
	{
		if (m.first == key)
			return m.second;
	}

	(*mmap)[key] = new ConcreteFlyweight(key);
	
	return (*mmap)[key];
}

int FlyweightFactory::GetFlywightCount()
{
	return mmap->size();
}
           

用戶端Client.h

#include"Flyweight.h"
#include"FlyweightFactory.h"
#include<iostream>
using std::cout;
using std::endl;

int main()
{
	FlyweightFactory *f = new FlyweightFactory();

	Flyweight *fx1 = f->GetGlyweightGategory("産品展示");
	fx1->Operation(User("小菜"));

	Flyweight *fx2 = f->GetGlyweightGategory("産品展示");
	fx2->Operation(User("大鳥"));

	Flyweight *fx3 = f->GetGlyweightGategory("産品展示");
	fx3->Operation(User("嬌嬌"));

	Flyweight *fb1 = f->GetGlyweightGategory("部落格");
	fb1->Operation(User("老頑童"));

	Flyweight *fb2 = f->GetGlyweightGategory("部落格");
	fb2->Operation(User("桃谷六仙"));

	Flyweight *fb3 = f->GetGlyweightGategory("部落格");
	fb3->Operation(User("南海鳄神"));

	cout << "網站分類個數" << f->GetFlywightCount() << endl;

	delete f;

	system("pause");
	return 0;
}
           

運作結果:

網站分類:       産品展示;       使用者:小菜
網站分類:       産品展示;       使用者:大鳥
網站分類:       産品展示;       使用者:嬌嬌
網站分類:       部落格;   使用者:老頑童
網站分類:       部落格;   使用者:桃谷六仙
網站分類:       部落格;   使用者:南海鳄神
網站分類個數2
請按任意鍵繼續. . .

           

繼續閱讀