模式动机(Flyweight Pattern):顾名思义,享元模式就是运用共享技术解决大量细粒度对象的复用问题。在享元模式中,由工厂负责维护一个享元池(Flyweight Pool),用于存储具有相同内部状态的一些对象。所谓内部状态,是指一个对象的特征,我们把大多数该类对象的不变特征确定为共享特征,将其抽象为一个类放到享元池中,对于可变的部分可以通过外部状态参数传入来解决。这样的话,如果客户要使用该类型的对象,只需通过工厂从享元池中取出即可,只有在享元池中不存在的对象才会被工厂创建出来。
模式结构图:
模式代码:
bt_享元模式.h:
1 #ifndef FP_H 2 #define FP_H 3 #include 4 #include
测试用例.cpp:
1 #include "bt_享元模式.h" 2 3 int main() 4 { 5 cout << "***** 享元模式测试 *****" << endl; 6 7 cout << endl; 8 FlyweightFactory* ff = new FlyweightFactory; 9 Flyweight* fw = ff->GetFlyweight("benxin"); // 第一次创建时不存在该对象10 fw->Operation("tuzi");11 12 cout << endl;13 Flyweight* fw2 = ff->GetFlyweight("benxin"); // 第二次创建时直接返回该对象14 fw2->Operation("tuzi");15 16 17 cout << endl;18 cout << "<< <直接使用非共享具体享元状态> >>" << endl; // 非共享内部状态可以直接实例化来使用19 Flyweight* fw3 = new UnsharedConcreteFlyweight;20 fw3->Operation("tuzi");21 22 delete fw3;23 delete fw;24 delete ff;25 26 return 0;27 } 直接使用非共享具体享元状态>
模式分析:
1> 享元模式中,选择频繁使用的类作为享元类,因为系统调用工厂也要产生时间上的开销,使用享元模式必须确保节约的空间开销是值得的;
2> 只有不会随着使用环境改变的状态才可以被设为共享状态;有些状态虽为内部状态,但是并不适合共享,对于这类状态,客户可以越过工厂直接实例化进行使用。
3> 享元模式的使用情况主要存在于系统中需要重复使用相同或类似的对象,如果每次都重复创建,可能会消耗大量内存空间,比如,文档编辑器中的字符类就适合作为享元类,而字符的位置参数适合作为外部状态使用,这样就可以加快文档的处理速度。