享元模式(Flyweight Pattern)

简介: 享元模式是一种结构型设计模式,通过共享对象来减少内存使用。它将对象分为共享和非共享部分,通过享元工厂管理和复用共享对象,适用于大量相似对象的场景,能显著节省内存并提高性能。典型应用包括文本编辑器中的字符样式和图形系统中的图形属性。

享元模式(Flyweight Pattern)详解

定义

享元模式是一种结构型设计模式,旨在通过共享对象来尽量减少内存的使用。享元模式通过将重复使用的对象分离成共享和非共享部分,达到复用的目的,从而有效节省内存。


核心概念

角色组成

  1. 享元(Flyweight)
    定义共享对象的接口,并可以提供内部状态(共享部分)和外部状态(非共享部分)的管理方法。
  2. 具体享元(Concrete Flyweight)
    实现享元接口,并实现共享部分的存储与管理。
  3. 享元工厂(FlyweightFactory)
    管理享元对象的创建与复用。确保享元对象被正确地共享和管理。
  4. 非共享享元(Unshared Concrete Flyweight)
    不共享的部分,用来存储具体的、每个对象独立的状态。

享元模式的类图


使用场景

  1. 大量对象的重复创建:当系统中存在大量相似对象,并且这些对象占用大量内存时,适合使用享元模式。
  2. 对象之间的共享性较强:当对象的某些部分是可以共享的(比如图形的颜色、字符的字体),而某些部分是特有的(如对象的位置、大小等),使用享元模式可以显著降低内存消耗。
  3. 提高性能和内存使用效率:通过共享相同状态,减少内存占用,提高程序性能。

优缺点分析

优点

  1. 节省内存:通过共享相同的对象,避免了内存的浪费。
  2. 提高性能:避免了重复创建相同的对象,提高了性能。
  3. 易于扩展:新的享元对象可以根据需要加入,而不影响现有的系统。

缺点

  1. 复杂性增加:享元模式通过共享和非共享的状态分离,使得系统结构变得更加复杂。
  2. 不能共享所有状态:不是所有的对象都能通过享元模式来共享,对于某些状态的对象可能无法进行共享。

使用案例

案例 1:文本编辑器

  • 描述:在文本编辑器中,每个字符都可以有不同的字体、大小和颜色,但大部分字符会使用相同的字体和颜色。通过享元模式,可以将这些重复的字符样式对象进行共享,以节省内存。
  • 实现:字体、颜色等属性作为共享部分,字符内容作为非共享部分。

案例 2:图形系统

  • 描述:在绘图应用中,多个相同类型的图形(如矩形、圆形)可能具有相同的属性(如颜色、填充等)。通过享元模式,可以将这些相同的属性提取为共享对象,只为每个图形的唯一位置和尺寸分配独立对象。
  • 实现:图形的形状作为共享部分,位置和尺寸作为非共享部分。

知识点对比表

特性 享元模式 不使用享元模式
对象创建方式 共享和复用相同的对象 每次创建新的对象
内存使用 节省内存,避免重复对象 内存使用较多,可能浪费空间
复杂度 需要享元工厂和状态管理 结构简单
使用场景 对象共享性强,内存紧张时 对象间差异较大时,适合直接创建

C++ 实现

#include <iostream>
#include <unordered_map>
#include <memory>
using namespace std;

// 享元接口
class Flyweight {
public:
   virtual void operation(const string& extrinsicState) const = 0;
   virtual ~Flyweight() = default;
};

// 具体享元
class ConcreteFlyweight : public Flyweight {
private:
   string intrinsicState; // 共享状态

public:
   explicit ConcreteFlyweight(string state) : intrinsicState(move(state)) {}

   void operation(const string& extrinsicState) const override {
       cout << "Intrinsic state: " << intrinsicState << ", Extrinsic state: " << extrinsicState << endl;
   }
};

// 享元工厂
class FlyweightFactory {
private:
   unordered_map<string, shared_ptr<Flyweight>> flyweights;

public:
   shared_ptr<Flyweight> getFlyweight(const string& key) {
       if (flyweights.find(key) == flyweights.end()) {
           flyweights[key] = make_shared<ConcreteFlyweight>(key);
       }
       return flyweights[key];
   }
};

// 客户端代码
int main() {
   FlyweightFactory factory;
   shared_ptr<Flyweight> f1 = factory.getFlyweight("SharedState1");
   shared_ptr<Flyweight> f2 = factory.getFlyweight("SharedState1");
   shared_ptr<Flyweight> f3 = factory.getFlyweight("SharedState2");

   f1->operation("UniqueState1");
   f2->operation("UniqueState2");
   f3->operation("UniqueState3");

   return 0;
}


C# 实现

using System;
using System.Collections.Generic;

// 享元接口
public abstract class Flyweight {
   public abstract void Operation(string extrinsicState);
}

// 具体享元
public class ConcreteFlyweight : Flyweight {
   private string intrinsicState; // 共享状态

   public ConcreteFlyweight(string state) {
       intrinsicState = state;
   }

   public override void Operation(string extrinsicState) {
       Console.WriteLine($"Intrinsic state: {intrinsicState}, Extrinsic state: {extrinsicState}");
   }
}

// 享元工厂
public class FlyweightFactory {
   private Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>();

   public Flyweight GetFlyweight(string key) {
       if (!flyweights.ContainsKey(key)) {
           flyweights[key] = new ConcreteFlyweight(key);
       }
       return flyweights[key];
   }
}

// 客户端代码
class Program {
   static void Main() {
       FlyweightFactory factory = new FlyweightFactory();
       Flyweight f1 = factory.GetFlyweight("SharedState1");
       Flyweight f2 = factory.GetFlyweight("SharedState1");
       Flyweight f3 = factory.GetFlyweight("SharedState2");

       f1.Operation("UniqueState1");
       f2.Operation("UniqueState2");
       f3.Operation("UniqueState3");
   }
}


总结

  1. 内存优化:享元模式通过共享对象,显著减少内存占用。
  2. 高效的对象管理:通过享元工厂管理共享对象的生命周期,避免不必要的对象创建。
  3. 适用场景:大量相似对象的场景,尤其是在需要节省内存时。
目录
相关文章
|
9天前
|
设计模式 C# C++
中介者模式(Mediator Pattern)
中介者模式是一种行为型设计模式,通过引入中介者对象来简化对象间的通信,减少多对象间的直接交互,降低系统耦合度。核心概念包括中介者、具体中介者和同事类。常见使用场景有聊天室、航空交通控制系统和GUI组件交互。优点是降低系统复杂度和提高灵活性,但中介者可能变得复杂,成为性能瓶颈。
22 3
|
7月前
|
设计模式 算法
设计模式 - 行为型模式_ 访问者模式Visitor Pattern
设计模式 - 行为型模式_ 访问者模式Visitor Pattern
78 1
设计模式 - 行为型模式_ 访问者模式Visitor Pattern
|
设计模式 存储 数据库
认真学习设计模式之享元模式(Flyweight Pattern)
认真学习设计模式之享元模式(Flyweight Pattern)
72 0
|
设计模式 BI
设计模式18 - 访问者模式【Visitor Pattern】
设计模式18 - 访问者模式【Visitor Pattern】
43 0
|
存储 Java 程序员
行为型模式 - 备忘录模式(Memento Pattern)
行为型模式 - 备忘录模式(Memento Pattern)
|
设计模式 Java 数据库
Java设计模式-享元模式(Flyweight Pattern)
Java设计模式-享元模式(Flyweight Pattern)
|
存储 缓存 Java
结构型模式 - 享元模式(Flyweight Pattern)
结构型模式 - 享元模式(Flyweight Pattern)
|
算法 Java 编译器
行为型模式 - 访问者模式(Visitor Pattern)
行为型模式 - 访问者模式(Visitor Pattern)
|
存储 设计模式 安全
结构型模式 - 组合模式(Composite Pattern)
结构型模式 - 组合模式(Composite Pattern)
结构型模式 - 装饰器模式(Decorator Pattern)
结构型模式 - 装饰器模式(Decorator Pattern)

热门文章

最新文章