结构型模式-享元模式

发布时间 2023-11-10 10:18:07作者: Qt小罗

1 什么是享元模式

享元模式(Flyweight Pattern)是一种以共享对象来减少内存使用和提高性能的设计模式。在享元模式中,通过共享尽可能多的相似对象来减少系统中对象的数量。这样可以节省内存和减少对象的创建和销毁所带来的开销。
享元模式的核心思想是将对象分为两个部分:内部状态(Intrinsic State)和外部状态(Extrinsic State)。内部状态是对象共享的部分,在享元模式中被存储于享元对象内部,而外部状态是对象的变化部分,由客户端在使用时传递给享元对象

2 举个例子

下面以一个简单的游戏角色创建为例来说明享元模式。假设有一个游戏中的角色类Character,它有内部状态type表示角色的类型(比如战士、法师等),而外部状态position表示角色的位置。
首先,我们创建一个享元工厂(Flyweight Factory)来管理和共享角色对象。享元工厂中有一个集合用于存储已经创建的角色对象,以内部状态作为键值。当需要创建角色时,首先检查集合中是否存在特定类型的角色对象,如果存在则直接返回共享的对象,如果不存在则创建新的对象并存储到集合中,然后返回该对象。

class Character
{
public:
    Character(const std::string& type) : type_(type) {}

    void Display(const std::string& position)
    {
        std::cout << "Character Type: " << type_ << ", Position: " << position << std::endl;
    }

private:
    std::string type_;
};

class CharacterFactory
{
public:
    Character* GetCharacter(const std::string& type)
    {
        if (characters_.find(type) != characters_.end())
        {
            return characters_[type];
        }

        Character* newCharacter = new Character(type);
        characters_[type] = newCharacter;
        return newCharacter;
    }

private:
    std::map<std::string, Character*> characters_;
};

客户端代码使用享元工厂来获取角色对象,并传递外部状态(位置):

int main()
{
    CharacterFactory characterFactory;

    Character* warrior = characterFactory.GetCharacter("Warrior");
    warrior->Display("X:10, Y:20");

    Character* mage = characterFactory.GetCharacter("Mage");
    mage->Display("X:30, Y:40");

    // 共享对象
    Character* warrior2 = characterFactory.GetCharacter("Warrior");
    warrior2->Display("X:50, Y:60");

    delete warrior;
    delete mage;
    delete warrior2;

    return 0;
}

在上述例子中,即使创建了多个战士角色对象,由于它们有相同的内部状态(“Warrior”),所以只有一个对象被真正创建,其他的对象直接引用已有的对象进行共享。这样可以有效地减少内存占用。

3 总结

享元模式通过共享对象来节省内存和提高性能,适用于有大量相似对象的场景,其中对象可以分为内部状态和外部状态。这样,通过共享相同的内部状态,可以减少对象的数量,并将对象的变化部分作为外部状态来传递和管理。