享元模式(Flyweight Pattern)
很好!你现在问的是非常经典的结构型设计模式 —— 享元模式(Flyweight Pattern)。
我将通过:
✅ 概念解释 + 🎯 使用动机 + 🐍 Python完整调用代码(含注释)+ 🧭 清晰类图 + 应用场景
来帮助你快速理解并掌握它。
🧠 一句话定义
享元模式通过共享内存中相同的对象,以减少内存占用,提高性能。
🎯 为什么需要?
当系统中存在大量内容相似的对象,而每个对象都单独存储会造成资源浪费时,我们:
- ✅ 抽取“可共享的部分”(称为内部状态)
- ✅ 与“不可共享的部分”(外部状态)分离
- ✅ 相同的对象就只保留一份,复用共享
📦 举个直观例子
假设你在一个文本编辑器中渲染 10 万个字符,每个字符(如字母 A)都是一个对象。
🔴 如果每个 A 都是独立对象:会创建成千上万个重复对象,占用内存大。
✅ 使用享元模式,所有 A 都共用一个对象实例,只记录它们的位置不同。
✅ 优点 vs ❌ 缺点
✅ 优点 | ❌ 缺点 |
---|---|
显著节省内存 | 逻辑结构复杂(内部/外部分离) |
提高系统性能 | 不适用于每个对象都不同的场景 |
对象可复用 | 管理共享状态比较困难 |
🐍 Python 示例:文档编辑器共享字符对象
✏️ 1️⃣ 享元类(可共享的部分)
class Character:def __init__(self, symbol):self.symbol = symbol # 内部状态:字符def display(self, font, position):# 外部状态:字体、位置print(f"字符: {self.symbol}, 字体: {font}, 位置: {position}")
🏭 2️⃣ 享元工厂(控制共享)
class CharacterFactory:def __init__(self):self._pool = {} # 享元池,缓存已创建的字符对象def get_char(self, symbol):if symbol not in self._pool:self._pool[symbol] = Character(symbol)return self._pool[symbol]def total_chars(self):return len(self._pool)
🧪 3️⃣ 客户端使用(外部状态变化)
factory = CharacterFactory()document = "aabbaabbbba"
for index, ch in enumerate(document):char_obj = factory.get_char(ch) # 复用共享对象char_obj.display(font="Arial", position=index)print(f"总共创建了 {factory.total_chars()} 个字符对象")
✅ 输出结果示意(节选):
字符: a, 字体: Arial, 位置: 0
字符: a, 字体: Arial, 位置: 1
字符: b, 字体: Arial, 位置: 2
...
总共创建了 2 个字符对象
即使渲染了 11 个字符,只创建了 2 个对象(a 和 b)。
🧭 类图(Mermaid)
✅ 应用场景总结
场景 | 描述 |
---|---|
文本渲染 | 大量字符复用相同字形对象 |
游戏开发 | 复用相同树、敌人、砖块等静态对象 |
数据可视化 | 坐标点对象可共享 |
网络连接池 | 数据库连接、线程、Socket 等资源池管理 |
🧠 口诀总结
享元模式就是:
✅ 小对象大量重复 → 提取可共享部分 → 对象复用,节省内存!
需要我帮你进一步用图形界面、地图渲染、或 AI 推理模型等场景来展示享元模式应用吗?我可以按你需求定制~