享元模式,又叫Flyweight,属于对象性能模式中的一种,主要解决系统中大量的细粒度的对象而带来不必要的系统开销,主要是指内存方面的开销。
模式定义
运用共享技术有效地支持大量细粒度的对象。 —《设计模式》 GoF
模式动机
系统中有大量的对象时,而且这些对象有些之间是相同的,或者说可以把这些对象分为几类,这种情况就可以使用相同的一类对象合并成使用相同的一个对象,因此系统就由之前很多重复的几类对象变为几个互不相同的对象,大大节约了系统的内存开销。
如何辨别这些对象是相同的?可以传入一个键值作为唯一标识码,如果这个键值相同,则返回其对应的对象,无需重复创建。
需要注意的事项,由于在内存中是多个业务共享了一个对象,为了避免改变这个对象,因此这个对象应该是只读的。
代码分析
假如现在需要画10个圆,现在有3中颜色,正常的设计应该是每一个圆对应一个对象,然后分别画出,但是由于每个圆的颜色只有3中,因此只要是颜色相同的圆,我们就可以使用同一个对象来创建,因此只需要3个对象即可。
画圆类
包括一个画圆的函数和string类型的颜色
class Circle
{
public:
Circle(std::string color);
~Circle();
std::string color;
virtual void shape();
};
Circle::Circle(std::string color)
{
this->color = color;
}
void Circle::shape()
{
std::cout << "shape circle : " << this->color << std::endl;
}
画圆工厂类
使用享元模式产生一个画圆的对象,使用一个map容器来存储所有互不相同的对象,这些对象通过颜色来区分,因此使用颜色作为键值
class ShapeFactory
{
private:
/* 创建一个对象池存储所有的对象,这是一个散列表,通过color找到对应的对象 */
std::map <std::string, Circle* > Circlepool;
public:
ShapeFactory();
~ShapeFactory();
Circle* createCircle(std::string color);
};
Circle* ShapeFactory::createCircle(std::string color)
{
std::map <std::string, Circle*> ::iterator item = Circlepool.find(color);
/* 查找是否已经创建过了 */
if (item != Circlepool.end())
{
return Circlepool[color];
}
else
{
std::cout << "create new circle \n";
Circle *circle = new Circle(color);
Circlepool[color] = circle;
return circle;
}
}
main函数
先构造一个工厂,再调用createCircle产生对象,是否产生了新对象有内部的享元模式进行判断
int main()
{
ShapeFactory *shapefactory = new ShapeFactory;
Circle *circle1 = shapefactory->createCircle("red");
circle1->shape();
Circle *circle2 = shapefactory->createCircle("red");
circle2->shape();
Circle *circle3 = shapefactory->createCircle("blue");
circle3->shape();
}
运行结果:
可以看到,创建第二个红色圆形的时候并没有创建新的对象,而是使用了第一个创建的对象,而创建第三份白色圆的时候又创建了新的对象,这就是使用享元模式创建对象的过程。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!