享元模式(flyweight)
1、作用
一些对象在使用一次后就可以销毁了,比如画一个圈,这个对象调用draw()函数后,这个对象就没有作用,除非再次画相同的圈。但是在应用中需要画很多圈,如果每次画一次圈都构造一个对象,这样内存消耗很多,构造销毁也很费时,这个时候就可以考虑一下享元模式,这样可以节省内存的开销。
2、实现方式
享元模式就很像:工厂模式+单例模式
(1)、有一个基类,在工厂中作为统一的接口
(2)、子类是特定功能的类,这类的属性分为两部分:外部属性和内部属性
内部属性:在构造该类的对象的时候就确定了,通过构造函数的参数来设置,不如圆圈的颜色:color。
外部属性:在对象构造以后可以修改,通过setXX()成员函数来设置,比如:圈的半径:radius。
(3)、工厂类:该类有点像单例模式的功能,在特点内部属性的对象已经存在(map中)时,返回存在的对象,不存在时构造一个新对象返回。
3、C++代码
Shape.h
#include#include #include <string> #ifndef __SHAPE__H__ #define __SHAPE__H__ using namespace std; class Shape { // 如果只有Circle这一种图形的话,可有没必要有这个基类,基类作用就是多态性,所有子类都指向基类。 virtual void draw() = 0; // 工厂模式必须有一个基类,应该,要产生很多子类对象,工厂的create统一为成基类对象返回。 }; // Flyweight模式可以认为是:工厂模式+单例模式 class Circle : public Shape { public: // 内部属性通过构造函数设置 Circle(const string &color):color(color) { cout<<"new Circle. color:"< endl; } // 外部属性通过set函数设置 void setX(const int &x) { this->x = x; } void setY(const int &y) { this->y = y; } void setRadius(const int &r) { this->radius = r; } // 可以认为是对象重复利用,一个对象------>多个屏幕上的圈(颜色相同), // 那种修改原有对象会影响原有效果的不能对象重用。说白了,这里的circle对象是一次性的,对象调用draw()函数后,就完成了使命,可以销毁 // flyweight模式则不销毁,以便后续有相同需求的时候使用。 void draw() { cout<<"color:"< 8)< " radius:"< 5)< " coordinate:("< ","< ")"<<endl; } private: string color; int x; int y; int radius; }; #endif
ShapeFactory.h
#include#include <string> #include
test.cc
#include "Shape.h" #include "ShapeFactory.h" int main() { Circle *circle = static_cast(ShapeFactory::getCircle("black")); circle->setX(0); circle->setY(0); circle->setRadius(10); circle->draw(); circle = static_cast (ShapeFactory::getCircle("black")); // black这个内部属性的对象已经存在,使用原有的对象 circle->setX(20); // 设置外部属性 circle->setY(30); circle->setRadius(11); circle->draw(); circle = static_cast (ShapeFactory::getCircle("red")); // red这个内部属性的对象不存在,新构造一个 circle->setX(20); // 设置外部属性 circle->setY(30); circle->setRadius(11); circle->draw(); return 0; }
输出: