享元模式 (Flyweight)
享元模式 是一种结构型计划模式,它通过共享对象来减少内存利用和对象创建的开销。当系统中有大量相似对象时,享元模式可以制止重复创建相同对象,从而节流内存。
意图
- 通过共享相同对象来减少内存消耗。
- 用于系统中存在大量相似对象的场景。
利用场景
- 大量相似对象:
- 系统中存在许多共享的对象,这些对象的状态大部门是相同的。
- 状态可以分为内部状态和外部状态:
- 内部状态:可以被共享的部门,不会随上下文变化。
- 外部状态:特定于场景的部门,不可共享,需要由客户端管理。
- 节流内存:
参与者角色
- 享元接口 (Flyweight)
- 具体享元 (ConcreteFlyweight)
- 非共享享元 (UnsharedFlyweight)
- 享元工厂 (FlyweightFactory)
- 客户端 (Client)
- 负责管理外部状态,并将外部状态与享元对象结合利用。
示例代码
以下代码展示了怎样利用享元模式来共享图形对象,例如圆形。
- #include <iostream>
- #include <string>
- #include <unordered_map>
- #include <memory>
- // 享元接口:图形
- class Shape {
- public:
- virtual ~Shape() = default;
- virtual void draw(const std::string& color) const = 0; // 外部状态为颜色
- };
- // 具体享元类:圆形
- class Circle : public Shape {
- private:
- int radius; // 内部状态:半径
- public:
- Circle(int r) : radius(r) {}
- void draw(const std::string& color) const override {
- std::cout << "Drawing a circle with radius " << radius << " and color " << color << std::endl;
- }
- };
- // 享元工厂:管理享元对象
- class ShapeFactory {
- private:
- std::unordered_map<int, std::shared_ptr<Shape>> shapes; // 缓存共享对象
- public:
- std::shared_ptr<Shape> getCircle(int radius) {
- if (shapes.find(radius) == shapes.end()) {
- shapes[radius] = std::make_shared<Circle>(radius);
- std::cout << "Creating a circle with radius " << radius << std::endl;
- }
- return shapes[radius];
- }
- };
- // 客户端代码
- int main() {
- ShapeFactory factory;
- // 获取共享的圆形对象
- auto circle1 = factory.getCircle(5);
- auto circle2 = factory.getCircle(10);
- auto circle3 = factory.getCircle(5); // 共享对象
- // 使用享元对象绘制
- circle1->draw("red"); // 外部状态:红色
- circle2->draw("blue"); // 外部状态:蓝色
- circle3->draw("green"); // 外部状态:绿色
- return 0;
- }
复制代码 代码解析
1. 享元接口 (Shape)
- 定义了 draw 方法,用于绘制图形,并吸取外部状态作为参数:
- class Shape {
- public:
- virtual ~Shape() = default;
- virtual void draw(const std::string& color) const = 0;
- };
复制代码 2. 具体享元类 (Circle)
- 实现了 Shape 接口,存储可以共享的内部状态(如半径):
- class Circle : public Shape {
- private:
- int radius; // 内部状态
- public:
- Circle(int r) : radius(r) {}
- void draw(const std::string& color) const override {
- std::cout << "Drawing a circle with radius " << radius << " and color " << color << std::endl;
- }
- };
复制代码 3. 享元工厂 (ShapeFactory)
- 负责管理享元对象,包管相同的内部状态只创建一个对象:
- class ShapeFactory {
- private:
- std::unordered_map<int, std::shared_ptr<Shape>> shapes; // 缓存共享对象
- public:
- std::shared_ptr<Shape> getCircle(int radius) {
- if (shapes.find(radius) == shapes.end()) {
- shapes[radius] = std::make_shared<Circle>(radius);
- std::cout << "Creating a circle with radius " << radius << std::endl;
- }
- return shapes[radius];
- }
- };
复制代码 4. 客户端
- 客户端通过 ShapeFactory 获取共享对象,并将外部状态与内部状态结合:
- auto circle1 = factory.getCircle(5); // 创建新对象
- auto circle3 = factory.getCircle(5); // 复用已有对象
- circle1->draw("red"); // 绘制红色圆形
- circle3->draw("green"); // 绘制绿色圆形
复制代码 优缺点
优点
- 减少内存利用:
- 通过共享对象,制止了重复创建相同对象,节流了内存。
- 提高系统性能:
- 灵活性高:
缺点
实用场景
- 系统有大量相似对象:
- 如笔墨处理系统中的字符对象,每个字符对象可以共享其字体、巨细等内部状态。
- 内存消耗成为瓶颈:
- 对象的状态可以分为内部状态和外部状态:
总结
享元模式通过共享相似对象来减少内存利用,是一种优化性能的告急模式。它实用于对象数量巨大且状态大部门可以共享的场景。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |