大话设计模式
1 享元模式(Flyweight)结构图
2 对享元模式的一些解释
概念:运用共享技术有效的支持大量细粒度的对象。【DP】
Flyweight类:是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
class Flyweight
{
public:
virtual void Operatiron(int extrinsicstate) = 0;
};
class ConcreteFlyweight :public Flyweight
{
public:
void Operatiron(int extrinsicstate) override
{
cout << "具体Flyweight" << extrinsicstate << endl;
}
};
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对象的操作时,将该状态传递给它。
也就是说,享元模式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
#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
#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
请按任意键继续. . .