大话设计模式26----享元模式

大话设计模式


1 享元模式(Flyweight)结构图




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  源代码结构图




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
请按任意键继续. . .










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值