(type, color);
std::cout // 静态成员初始化
std::map<:string std::shared_ptr>> TreeFactory::pool;
// 外层封装类:代表一棵树
class Tree {
private:
int x, y;
std::shared_ptr type;
public:
Tree(int x, int y, const std::shared_ptr& type) : x(x), y(y), type(type) {}
void draw() const {
type-youjiankuohaophpcndraw(x, y);
}};
// 森林类,包含多棵树
class Forest {
private:
std::vector trees;
public:
void plantTree(int x, int y, const std::string& type, const std::string& color) {
auto treeType = TreeFactory::getTreeType(type, color);
trees.emplace_back(x, y, treeType);
}
void draw() const {
for (const auto& tree : trees) {
tree.draw();
}
}};
使用示例:
int main() {
Forest forest;
forest.plantTree(1, 2, "Oa
k", "Green");
forest.plantTree(3, 4, "Oak", "Green"); // 共享同一个 TreeType
forest.plantTree(5, 6, "Pine", "DarkGreen");
forest.draw();
return 0;
}
为什么能节约内存?
在这个例子中,即使我们创建了上百棵“Oak - Green”类型的树,也只会有一个 TreeType 实例被创建并共享。所有树对象共用这个实例,只保存自己的位置信息。这样大大减少了内存开销,尤其适合大规模相似对象的场景,比如图形系统、文本编辑器中的字符格式、游戏中的粒子效果等。
注意事项与适用场景
- 享元适合对象数量巨大且内部状态高度重复的情况。
- 外部状态必须由客户端传入,不能放在享元对象内部。
- 线程安全需额外处理,若多线程访问享元工厂,应加锁保护缓存map。
- 过度使用可能增加代码复杂度,应权衡是否真的需要节省内存。
基本上就这些。通过共享不变状态,Flyweight模式有效降低了内存占用,是性能优化中的实用技巧之一。不复杂但容易忽略。