概述
面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。
- 享元模式通过共享技术实现相同或相似对象的重用。
- 在享元模式中可以共享的相同内容称为内部状态(
IntrinsicState
),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
- 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(
Flyweight Pool
)用于存储具有相同内部状态的享元对象。
- 在享元模式中共享的是享元对象的内部状态,外部状态需要通过环境来设置。在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也称为细粒度对象。享元模式的目的就是使用共享技术来实现大量细粒度对象的复用。
定义
运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
角色
Flyweight:
抽象享元类
ConcreteFlyweight:
具体享元类
UnsharedConcreteFlyweight:
非共享具体享元类
FlyweightFactory:
享元工厂类
场景
- 当一个类的一个实例可用于提供许多“虚拟实例”时
- 当满足以下所有条件时
- 应用程序使用大量对象
- 由于对象数量巨大,因此存储成本很高
- 大多数对象状态可以是外部的
- 一旦删除了外部状态,则可以用相对较少的共享对象替换许多对象组
- 该应用程序不依赖于对象标识
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
//抽象享元类 class Flyweight { public: virtual ~Flyweight() {} virtual void operation() = 0; //... }; //非共享具体享元类 class UnsharedConcreteFlyweight : public Flyweight { public: UnsharedConcreteFlyweight(const int intrinsic_state) : state(intrinsic_state) { } ~UnsharedConcreteFlyweight() {} void operation() { std::cout << "Unshared Flyweight with state" << std::endl; } //... private: int state; //... }; //具体享元类 class ConcreteFlyweight : public Flyweight { public: ConcreteFlyweight(const int all_state):state(all_state) { } ~ConcreteFlyweight() {} void operation() { std::cout << "Concrete Flyweight with state" << state << std::endl; } //... private: int state; //... }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
//享元工厂类 class FlyweightFactory { public: ~FlyweightFactory() { for (auto it = files.begin();it != files.end();it++) delete it->second; files.clear(); } Flyweight * getFlyweight(const int key) { if (files.find(key) != files.end()) return files[key]; Flyweight * fly = new ConcreteFlyweight(key); files.insert(std::pair<int,Flyweight*>(key,fly)); return fly; } //... private: std::map<int,Flyweight*> files; //... }; |
|
auto main()->int { FlyweightFactory * factory = new FlyweightFactory(); factory->getFlyweight(1)->operation(); factory->getFlyweight(2)->operation(); delete factory; return 0; } |