第五章:原型模式 - 克隆大法的大师

第五章:原型模式 - 克隆大法的大师

故事延续:幻影分身的奇妙艺术

在Builder展示完他的精细构建艺术后,Prototype身形飘忽地走出,他那幻影重重的身影吸引了所有人的注意。这位神秘的高手时而化作三人,时而合为一体,令人难以捕捉。

"Builder兄的逐步构建确实精妙," Prototype发出空灵的笑声,"但有时候我们并不需要从零开始创建对象。我的武学核心在于------通过复制现有对象来创建新对象。这在创建成本高昂或需要快速创建相似对象时特别有用!"

原型模式的武学精要

核心心法

Prototype双手结印,空中浮现出多个相同的幻影:"我的八字真言是------克隆复制,快速创建。通过实现一个克隆方法,我可以快速创建对象的副本,避免重新执行昂贵的创建过程。"

C++ 代码实战
cpp 复制代码
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <sstream>

// 抽象原型接口
class Prototype {
public:
    virtual ~Prototype() = default;
    virtual std::unique_ptr<Prototype> clone() const = 0;
    virtual void display() const = 0;
    virtual std::string getType() const = 0;
    virtual void customize(const std::string& customization) = 0;
};

// 具体原型:游戏角色
class GameCharacter : public Prototype {
private:
    std::string name_;
    std::string characterClass_;
    int level_;
    int health_;
    int mana_;
    std::vector<std::string> skills_;
    std::string equipment_;
    
public:
    GameCharacter(const std::string& name, const std::string& characterClass, 
                  int level, int health, int mana, 
                  const std::vector<std::string>& skills, const std::string& equipment)
        : name_(name), characterClass_(characterClass), level_(level), 
          health_(health), mana_(mana), skills_(skills), equipment_(equipment) {}
    
    // 克隆方法 - 核心所在
    std::unique_ptr<Prototype> clone() const override {
        std::cout << "👥 克隆角色: " << name_ << std::endl;
        return std::make_unique<GameCharacter>(*this);
    }
    
    void display() const override {
        std::cout << "\n🎭 角色信息:" << std::endl;
        std::cout << "  👤 名称: " << name_ << std::endl;
        std::cout << "  🎯 职业: " << characterClass_ << std::endl;
        std::cout << "  📊 等级: " << level_ << std::endl;
        std::cout << "  ❤️ 生命值: " << health_ << std::endl;
        std::cout << "  🔮 法力值: " << mana_ << std::endl;
        
        std::cout << "  🎯 技能: ";
        for (const auto& skill : skills_) {
            std::cout << skill << " ";
        }
        std::cout << std::endl;
        
        std::cout << "  ⚔️ 装备: " << equipment_ << std::endl;
    }
    
    std::string getType() const override {
        return characterClass_;
    }
    
    void customize(const std::string& customization) override {
        name_ = customization;
        std::cout << "🎨 自定义角色名为: " << name_ << std::endl;
    }
    
    // 修改等级
    void setLevel(int level) {
        level_ = level;
        std::cout << "⬆️ 设置等级为: " << level_ << std::endl;
    }
    
    // 添加技能
    void addSkill(const std::string& skill) {
        skills_.push_back(skill);
        std::cout << "➕ 添加技能: " << skill << std::endl;
    }
    
    // 更换装备
    void changeEquipment(const std::string& equipment) {
        equipment_ = equipment;
        std::cout << "🔄 更换装备为: " << equipment_ << std::endl;
    }
    
    std::string getDescription() const {
        std::stringstream ss;
        ss << name_ << " (Lv." << level_ << " " << characterClass_ << ")";
        return ss.str();
    }
};

// 具体原型:魔法武器
class MagicWeapon : public Prototype {
private:
    std::string name_;
    std::string weaponType_;
    int damage_;
    int magicPower_;
    std::string element_;
    std::vector<std::string> enchantments_;
    
public:
    MagicWeapon(const std::string& name, const std::string& weaponType, 
                int damage, int magicPower, const std::string& element,
                const std::vector<std::string>& enchantments)
        : name_(name), weaponType_(weaponType), damage_(damage), 
          magicPower_(magicPower), element_(element), enchantments_(enchantments) {}
    
    std::unique_ptr<Prototype> clone() const override {
        std::cout << "🔮 克隆魔法武器: " << name_ << std::endl;
        return std::make_unique<MagicWeapon>(*this);
    }
    
    void display() const override {
        std::cout << "\n⚔️ 魔法武器信息:" << std::endl;
        std::cout << "  📛 名称: " << name_ << std::endl;
        std::cout << "  🔧 类型: " << weaponType_ << std::endl;
        std::cout << "  💥 物理伤害: " << damage_ << std::endl;
        std::cout << "  ✨ 魔法威力: " << magicPower_ << std::endl;
        std::cout << "  🌟 元素属性: " << element_ << std::endl;
        
        std::cout << "  🎇 附魔效果: ";
        for (const auto& enchantment : enchantments_) {
            std::cout << enchantment << " ";
        }
        std::cout << std::endl;
    }
    
    std::string getType() const override {
        return weaponType_;
    }
    
    void customize(const std::string& customization) override {
        name_ = customization;
        std::cout << "🎨 自定义武器名为: " << name_ << std::endl;
    }
    
    // 增强武器
    void enhance(int additionalDamage, int additionalMagic) {
        damage_ += additionalDamage;
        magicPower_ += additionalMagic;
        std::cout << "⬆️ 增强武器: +" << additionalDamage << "伤害, +" << additionalMagic << "魔法" << std::endl;
    }
    
    // 添加附魔
    void addEnchantment(const std::string& enchantment) {
        enchantments_.push_back(enchantment);
        std::cout << "✨ 添加附魔: " << enchantment << std::endl;
    }
};

// 具体原型:游戏地图
class GameMap : public Prototype {
private:
    std::string name_;
    std::string terrainType_;
    int width_;
    int height_;
    std::vector<std::string> landmarks_;
    std::string weather_;
    int difficulty_;
    
public:
    GameMap(const std::string& name, const std::string& terrainType, 
            int width, int height, const std::vector<std::string>& landmarks,
            const std::string& weather, int difficulty)
        : name_(name), terrainType_(terrainType), width_(width), height_(height),
          landmarks_(landmarks), weather_(weather), difficulty_(difficulty) {}
    
    std::unique_ptr<Prototype> clone() const override {
        std::cout << "🗺️ 克隆游戏地图: " << name_ << std::endl;
        return std::make_unique<GameMap>(*this);
    }
    
    void display() const override {
        std::cout << "\n🗺️ 地图信息:" << std::endl;
        std::cout << "  📛 名称: " << name_ << std::endl;
        std::cout << "  🌄 地形: " << terrainType_ << std::endl;
        std::cout << "  📏 尺寸: " << width_ << "x" << height_ << std::endl;
        std::cout << "  🌤️ 天气: " << weather_ << std::endl;
        std::cout << "  ⚠️ 难度: " << difficulty_ << std::endl;
        
        std::cout << "  🏰 地标: ";
        for (const auto& landmark : landmarks_) {
            std::cout << landmark << " ";
        }
        std::cout << std::endl;
    }
    
    std::string getType() const override {
        return terrainType_;
    }
    
    void customize(const std::string& customization) override {
        name_ = customization;
        std::cout << "🎨 自定义地图名为: " << name_ << std::endl;
    }
    
    // 改变天气
    void changeWeather(const std::string& weather) {
        weather_ = weather;
        std::cout << "🌤️ 改变天气为: " << weather_ << std::endl;
    }
    
    // 调整难度
    void adjustDifficulty(int difficulty) {
        difficulty_ = difficulty;
        std::cout << "⚠️ 调整难度为: " << difficulty_ << std::endl;
    }
};

// 原型管理器:存储和管理原型实例
class PrototypeManager {
private:
    std::unordered_map<std::string, std::unique_ptr<Prototype>> prototypes_;
    
public:
    // 注册原型
    void registerPrototype(const std::string& key, std::unique_ptr<Prototype> prototype) {
        prototypes_[key] = std::move(prototype);
        std::cout << "📝 注册原型: " << key << std::endl;
    }
    
    // 克隆原型
    std::unique_ptr<Prototype> clonePrototype(const std::string& key) {
        auto it = prototypes_.find(key);
        if (it != prototypes_.end()) {
            return it->second->clone();
        }
        std::cout << "❌ 未找到原型: " << key << std::endl;
        return nullptr;
    }
    
    // 批量克隆
    std::vector<std::unique_ptr<Prototype>> cloneMultiple(const std::string& key, int count) {
        std::vector<std::unique_ptr<Prototype>> clones;
        for (int i = 0; i < count; ++i) {
            auto clone = clonePrototype(key);
            if (clone) {
                clones.push_back(std::move(clone));
            }
        }
        return clones;
    }
    
    // 显示所有原型
    void displayAllPrototypes() const {
        std::cout << "\n📚 原型管理器中的所有原型:" << std::endl;
        for (const auto& pair : prototypes_) {
            std::cout << "  🔑 键: " << pair.first << " | 类型: " << pair.second->getType() << std::endl;
        }
    }
    
    // 获取所有原型键
    std::vector<std::string> getAllKeys() const {
        std::vector<std::string> keys;
        for (const auto& pair : prototypes_) {
            keys.push_back(pair.first);
        }
        return keys;
    }
};

UML 武功秘籍图

manages <<interface>> Prototype +clone() +display() : void +getType() : string +customize(string) : void GameCharacter -string name_ -string characterClass_ -int level_ -int health_ -int mana_ -vector<string> skills_ -string equipment_ +clone() +display() : void +getType() : string +customize(string) : void +setLevel(int) : void +addSkill(string) : void +changeEquipment(string) : void +getDescription() : string MagicWeapon -string name_ -string weaponType_ -int damage_ -int magicPower_ -string element_ -vector<string> enchantments_ +clone() +display() : void +getType() : string +customize(string) : void +enhance(int, int) : void +addEnchantment(string) : void GameMap -string name_ -string terrainType_ -int width_ -int height_ -vector<string> landmarks_ -string weather_ -int difficulty_ +clone() +display() : void +getType() : string +customize(string) : void +changeWeather(string) : void +adjustDifficulty(int) : void PrototypeManager -unordered_map<string, Prototype*> prototypes_ +registerPrototype(string, Prototype*) : void +clonePrototype(string) +cloneMultiple(string, int) +displayAllPrototypes() : void +getAllKeys() : vector<string>

实战演练:游戏对象复制系统

cpp 复制代码
#include <random>
#include <algorithm>

// 更复杂的游戏对象复制系统

// 具体原型:怪物模板
class MonsterTemplate : public Prototype {
private:
    std::string name_;
    std::string monsterType_;
    int baseHealth_;
    int baseAttack_;
    int baseDefense_;
    std::vector<std::string> abilities_;
    std::string lootTable_;
    int experienceValue_;
    
public:
    MonsterTemplate(const std::string& name, const std::string& monsterType,
                   int baseHealth, int baseAttack, int baseDefense,
                   const std::vector<std::string>& abilities,
                   const std::string& lootTable, int experienceValue)
        : name_(name), monsterType_(monsterType), baseHealth_(baseHealth),
          baseAttack_(baseAttack), baseDefense_(baseDefense), abilities_(abilities),
          lootTable_(lootTable), experienceValue_(experienceValue) {}
    
    std::unique_ptr<Prototype> clone() const override {
        std::cout << "👹 克隆怪物模板: " << name_ << std::endl;
        return std::make_unique<MonsterTemplate>(*this);
    }
    
    void display() const override {
        std::cout << "\n👹 怪物模板信息:" << std::endl;
        std::cout << "  📛 名称: " << name_ << std::endl;
        std::cout << "  🎯 类型: " << monsterType_ << std::endl;
        std::cout << "  ❤️ 基础生命: " << baseHealth_ << std::endl;
        std::cout << "  ⚔️ 基础攻击: " << baseAttack_ << std::endl;
        std::cout << "  🛡️ 基础防御: " << baseDefense_ << std::endl;
        std::cout << "  💰 经验值: " << experienceValue_ << std::endl;
        std::cout << "  🎁 掉落表: " << lootTable_ << std::endl;
        
        std::cout << "  🎯 能力: ";
        for (const auto& ability : abilities_) {
            std::cout << ability << " ";
        }
        std::cout << std::endl;
    }
    
    std::string getType() const override {
        return monsterType_;
    }
    
    void customize(const std::string& customization) override {
        name_ = customization;
        std::cout << "🎨 自定义怪物名为: " << name_ << std::endl;
    }
    
    // 生成随机变体
    std::unique_ptr<MonsterTemplate> createVariant() const {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> healthDis(-10, 10);
        std::uniform_int_distribution<> attackDis(-5, 5);
        
        auto variant = std::make_unique<MonsterTemplate>(*this);
        variant->baseHealth_ += healthDis(gen);
        variant->baseAttack_ += attackDis(gen);
        variant->name_ += "变体";
        
        std::cout << "🎲 创建怪物变体: " << variant->name_ << std::endl;
        return variant;
    }
    
    // 获取基础属性
    int getBaseHealth() const { return baseHealth_; }
    int getBaseAttack() const { return baseAttack_; }
    int getBaseDefense() const { return baseDefense_; }
};

// 具体原型:任务模板
class QuestTemplate : public Prototype {
private:
    std::string title_;
    std::string questType_;
    std::string description_;
    std::vector<std::string> objectives_;
    std::vector<std::string> rewards_;
    int requiredLevel_;
    std::string zone_;
    
public:
    QuestTemplate(const std::string& title, const std::string& questType,
                  const std::string& description, const std::vector<std::string>& objectives,
                  const std::vector<std::string>& rewards, int requiredLevel, const std::string& zone)
        : title_(title), questType_(questType), description_(description),
          objectives_(objectives), rewards_(rewards), requiredLevel_(requiredLevel), zone_(zone) {}
    
    std::unique_ptr<Prototype> clone() const override {
        std::cout << "📜 克隆任务模板: " << title_ << std::endl;
        return std::make_unique<QuestTemplate>(*this);
    }
    
    void display() const override {
        std::cout << "\n📜 任务模板信息:" << std::endl;
        std::cout << "  📛 标题: " << title_ << std::endl;
        std::cout << "  🎯 类型: " << questType_ << std::endl;
        std::cout << "  📝 描述: " << description_ << std::endl;
        std::cout << "  📊 要求等级: " << requiredLevel_ << std::endl;
        std::cout << "  🗺️ 区域: " << zone_ << std::endl;
        
        std::cout << "  🎯 目标: " << std::endl;
        for (const auto& objective : objectives_) {
            std::cout << "    - " << objective << std::endl;
        }
        
        std::cout << "  🎁 奖励: " << std::endl;
        for (const auto& reward : rewards_) {
            std::cout << "    - " << reward << std::endl;
        }
    }
    
    std::string getType() const override {
        return questType_;
    }
    
    void customize(const std::string& customization) override {
        title_ = customization;
        std::cout << "🎨 自定义任务标题为: " << title_ << std::endl;
    }
    
    // 生成日常任务
    std::unique_ptr<QuestTemplate> createDailyQuest() const {
        auto dailyQuest = std::make_unique<QuestTemplate>(*this);
        dailyQuest->title_ = "日常:" + title_;
        dailyQuest->requiredLevel_ = 1; // 日常任务等级要求低
        
        std::cout << "📅 创建日常任务: " << dailyQuest->title_ << std::endl;
        return dailyQuest;
    }
};

// 高级原型管理器
class AdvancedPrototypeManager {
private:
    std::unordered_map<std::string, std::unique_ptr<Prototype>> prototypes_;
    std::unordered_map<std::string, std::vector<std::string>> categories_;
    
public:
    void registerPrototype(const std::string& key, std::unique_ptr<Prototype> prototype, const std::string& category = "default") {
        prototypes_[key] = std::move(prototype);
        categories_[category].push_back(key);
        std::cout << "📝 注册原型到分类 '" << category << "': " << key << std::endl;
    }
    
    std::unique_ptr<Prototype> clonePrototype(const std::string& key) {
        auto it = prototypes_.find(key);
        if (it != prototypes_.end()) {
            return it->second->clone();
        }
        return nullptr;
    }
    
    // 按分类克隆
    std::vector<std::unique_ptr<Prototype>> cloneByCategory(const std::string& category) {
        std::vector<std::unique_ptr<Prototype>> clones;
        auto it = categories_.find(category);
        if (it != categories_.end()) {
            for (const auto& key : it->second) {
                auto clone = clonePrototype(key);
                if (clone) {
                    clones.push_back(std::move(clone));
                }
            }
        }
        return clones;
    }
    
    // 获取分类列表
    std::vector<std::string> getCategories() const {
        std::vector<std::string> categoryList;
        for (const auto& pair : categories_) {
            categoryList.push_back(pair.first);
        }
        return categoryList;
    }
    
    // 显示分类内容
    void displayCategory(const std::string& category) const {
        auto it = categories_.find(category);
        if (it != categories_.end()) {
            std::cout << "\n📂 分类 '" << category << "' 中的原型:" << std::endl;
            for (const auto& key : it->second) {
                auto prototypeIt = prototypes_.find(key);
                if (prototypeIt != prototypes_.end()) {
                    std::cout << "  🔑 " << key << " -> " << prototypeIt->second->getType() << std::endl;
                }
            }
        }
    }
};

// 原型工厂:基于原型的对象创建
class PrototypeFactory {
private:
    AdvancedPrototypeManager manager_;
    
public:
    PrototypeFactory() {
        initializePrototypes();
    }
    
    void initializePrototypes() {
        // 初始化角色原型
        std::vector<std::string> warriorSkills = {"重击", "防御姿态", "旋风斩"};
        manager_.registerPrototype("warrior", 
            std::make_unique<GameCharacter>("战士模板", "战士", 1, 100, 20, warriorSkills, "训练用剑"), "characters");
        
        std::vector<std::string> mageSkills = {"火球术", "寒冰箭", "魔法盾"};
        manager_.registerPrototype("mage", 
            std::make_unique<GameCharacter>("法师模板", "法师", 1, 60, 100, mageSkills, "学徒法杖"), "characters");
        
        // 初始化武器原型
        std::vector<std::string> swordEnchantments = {"锋利", "耐久"};
        manager_.registerPrototype("fire_sword", 
            std::make_unique<MagicWeapon>("火焰剑", "剑", 25, 15, "火", swordEnchantments), "weapons");
        
        std::vector<std::string> staffEnchantments = {"智慧", "魔力恢复"};
        manager_.registerPrototype("ice_staff", 
            std::make_unique<MagicWeapon>("寒冰法杖", "法杖", 10, 30, "冰", staffEnchantments), "weapons");
        
        // 初始化怪物原型
        std::vector<std::string> goblinAbilities = {"投掷", "逃跑"};
        manager_.registerPrototype("goblin", 
            std::make_unique<MonsterTemplate>("哥布林", "普通", 50, 8, 3, goblinAbilities, "普通掉落", 10), "monsters");
        
        std::vector<std::string> dragonAbilities = {"喷火", "飞行", "威压"};
        manager_.registerPrototype("dragon", 
            std::make_unique<MonsterTemplate>("巨龙", "BOSS", 500, 50, 20, dragonAbilities, "稀有掉落", 1000), "monsters");
        
        // 初始化任务原型
        std::vector<std::string> killObjectives = {"杀死10只哥布林", "收集5个战利品"};
        std::vector<std::string> killRewards = {"100金币", "经验值200"};
        manager_.registerPrototype("goblin_hunt", 
            std::make_unique<QuestTemplate>("哥布林讨伐", "狩猎", "清理哥布林营地", killObjectives, killRewards, 5, "起始森林"), "quests");
    }
    
    // 创建角色
    std::unique_ptr<GameCharacter> createCharacter(const std::string& type, const std::string& name) {
        auto prototype = manager_.clonePrototype(type);
        if (auto character = dynamic_cast<GameCharacter*>(prototype.get())) {
            prototype.release(); // 避免双重删除
            auto uniqueChar = std::unique_ptr<GameCharacter>(character);
            uniqueChar->customize(name);
            return uniqueChar;
        }
        return nullptr;
    }
    
    // 创建怪物军团
    std::vector<std::unique_ptr<MonsterTemplate>> createMonsterArmy(const std::string& type, int count) {
        std::vector<std::unique_ptr<MonsterTemplate>> army;
        for (int i = 0; i < count; ++i) {
            auto prototype = manager_.clonePrototype(type);
            if (auto monster = dynamic_cast<MonsterTemplate*>(prototype.get())) {
                prototype.release();
                auto uniqueMonster = std::unique_ptr<MonsterTemplate>(monster);
                uniqueMonster->customize(uniqueMonster->getType() + std::to_string(i + 1));
                army.push_back(std::move(uniqueMonster));
            }
        }
        return army;
    }
    
    // 显示所有可用原型
    void displayAvailablePrototypes() {
        std::cout << "\n🔄 可用的原型分类:" << std::endl;
        auto categories = manager_.getCategories();
        for (const auto& category : categories) {
            manager_.displayCategory(category);
        }
    }
};

原型模式的招式解析

招式一:深拷贝与浅拷贝
cpp 复制代码
// 演示深拷贝问题的类
class ShallowCopyExample {
private:
    std::string* data_;
    int size_;
    
public:
    ShallowCopyExample(const std::string& data, int size) : size_(size) {
        data_ = new std::string(data);
    }
    
    // 默认拷贝构造函数 - 浅拷贝(有问题)
    ShallowCopyExample(const ShallowCopyExample& other) 
        : data_(other.data_), size_(other.size_) { // 错误:共享指针
    }
    
    // 正确的深拷贝构造函数
    ShallowCopyExample(const ShallowCopyExample& other, bool deepCopy) 
        : size_(other.size_) {
        if (deepCopy) {
            data_ = new std::string(*other.data_); // 深拷贝:创建新字符串
        } else {
            data_ = other.data_; // 浅拷贝:共享字符串
        }
    }
    
    ~ShallowCopyExample() {
        delete data_;
    }
    
    void display() const {
        std::cout << "数据: " << (data_ ? *data_ : "空") << ", 大小: " << size_ << std::endl;
    }
};

// 正确的原型实现示例
class CorrectPrototype {
private:
    std::string name_;
    std::vector<std::string>* items_; // 需要深拷贝的指针成员
    
public:
    CorrectPrototype(const std::string& name, const std::vector<std::string>& items) 
        : name_(name) {
        items_ = new std::vector<std::string>(items); // 动态分配
    }
    
    // 拷贝构造函数 - 实现深拷贝
    CorrectPrototype(const CorrectPrototype& other) 
        : name_(other.name_) {
        items_ = new std::vector<std::string>(*other.items_); // 深拷贝向量
    }
    
    // 克隆方法
    std::unique_ptr<CorrectPrototype> clone() const {
        return std::make_unique<CorrectPrototype>(*this); // 使用拷贝构造函数
    }
    
    ~CorrectPrototype() {
        delete items_;
    }
    
    void addItem(const std::string& item) {
        items_->push_back(item);
    }
    
    void display() const {
        std::cout << "名称: " << name_ << ", 物品: ";
        for (const auto& item : *items_) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    }
};
招式二:原型注册表增强版
cpp 复制代码
// 支持版本控制的原型管理器
class VersionedPrototypeManager {
private:
    std::unordered_map<std::string, std::vector<std::unique_ptr<Prototype>>> versionedPrototypes_;
    std::unordered_map<std::string, int> currentVersions_;
    
public:
    void registerPrototype(const std::string& key, std::unique_ptr<Prototype> prototype, int version = 1) {
        if (versionedPrototypes_.find(key) == versionedPrototypes_.end()) {
            versionedPrototypes_[key] = std::vector<std::unique_ptr<Prototype>>();
        }
        
        // 确保有足够的空间
        if (versionedPrototypes_[key].size() < static_cast<size_t>(version)) {
            versionedPrototypes_[key].resize(version);
        }
        
        versionedPrototypes_[key][version - 1] = std::move(prototype);
        currentVersions_[key] = version;
        
        std::cout << "📝 注册原型 " << key << " 版本 " << version << std::endl;
    }
    
    std::unique_ptr<Prototype> clonePrototype(const std::string& key, int version = -1) {
        auto it = versionedPrototypes_.find(key);
        if (it != versionedPrototypes_.end()) {
            int ver = (version == -1) ? currentVersions_[key] : version;
            if (ver > 0 && ver <= static_cast<int>(it->second.size()) && it->second[ver - 1]) {
                return it->second[ver - 1]->clone();
            }
        }
        return nullptr;
    }
    
    // 升级原型版本
    void upgradePrototype(const std::string& key, std::unique_ptr<Prototype> newVersion) {
        int newVersionNumber = currentVersions_[key] + 1;
        registerPrototype(key, std::move(newVersion), newVersionNumber);
        std::cout << "⬆️ 升级原型 " << key << " 到版本 " << newVersionNumber << std::endl;
    }
    
    // 获取所有版本信息
    void displayVersionInfo(const std::string& key) const {
        auto it = versionedPrototypes_.find(key);
        if (it != versionedPrototypes_.end()) {
            std::cout << "\n📊 原型 " << key << " 的版本信息:" << std::endl;
            for (size_t i = 0; i < it->second.size(); ++i) {
                if (it->second[i]) {
                    std::cout << "  版本 " << (i + 1) << ": " << it->second[i]->getType() 
                              << " (当前: " << ((i + 1) == static_cast<size_t>(currentVersions_.at(key)) ? "是" : "否") << ")" << std::endl;
                }
            }
        }
    }
};

完整测试代码

cpp 复制代码
// 测试原型模式
void testPrototypePattern() {
    std::cout << "=== 原型模式测试开始 ===" << std::endl;
    
    // 测试基础原型功能
    std::cout << "\n--- 基础原型功能测试 ---" << std::endl;
    
    // 创建原始角色
    std::vector<std::string> skills = {"火球术", "治疗术", "传送"};
    auto originalMage = std::make_unique<GameCharacter>("大法师", "法师", 50, 200, 500, skills, "传说法杖");
    
    std::cout << "原始角色:" << std::endl;
    originalMage->display();
    
    // 克隆角色
    auto clonedMage = originalMage->clone();
    std::cout << "\n克隆后的角色:" << std::endl;
    if (clonedMage) {
        clonedMage->customize("克隆法师");
        clonedMage->setLevel(1);
        clonedMage->display();
    }
    
    // 测试原型管理器
    std::cout << "\n--- 原型管理器测试 ---" << std::endl;
    PrototypeManager manager;
    
    // 注册一些原型
    std::vector<std::string> warriorSkills = {"冲锋", "斩击",格挡"};
    manager.registerPrototype("basic_warrior", 
        std::make_unique<GameCharacter>("基础战士", "战士", 1, 100, 30, warriorSkills, "铁剑"));
    
    std::vector<std::string> bowEnchantments = {"精准", "速射"};
    manager.registerPrototype("hunters_bow", 
        std::make_unique<MagicWeapon>("猎人弓", "弓", 18, 5, "自然", bowEnchantments));
    
    // 显示所有原型
    manager.displayAllPrototypes();
    
    // 克隆多个对象
    std::cout << "\n--- 批量克隆测试 ---" << std::endl;
    auto warriorClones = manager.cloneMultiple("basic_warrior", 3);
    for (size_t i = 0; i < warriorClones.size(); ++i) {
        warriorClones[i]->customize("战士副本" + std::to_string(i + 1));
        warriorClones[i]->display();
    }
    
    // 测试高级原型系统
    std::cout << "\n--- 高级原型系统测试 ---" << std::endl;
    PrototypeFactory factory;
    factory.displayAvailablePrototypes();
    
    // 创建自定义角色
    auto customWarrior = factory.createCharacter("warrior", "我的战士");
    if (customWarrior) {
        customWarrior->setLevel(10);
        customWarrior->addSkill("狂暴");
        customWarrior->display();
    }
    
    // 创建怪物军团
    std::cout << "\n--- 怪物军团测试 ---" << std::endl;
    auto goblinArmy = factory.createMonsterArmy("goblin", 5);
    for (const auto& goblin : goblinArmy) {
        goblin->display();
    }
    
    // 测试版本控制原型管理器
    std::cout << "\n--- 版本控制原型测试 ---" << std::endl;
    VersionedPrototypeManager versionManager;
    
    // 注册不同版本的武器
    std::vector<std::string> v1Enchantments = {"基础锋利"};
    versionManager.registerPrototype("magic_sword", 
        std::make_unique<MagicWeapon>("魔法剑v1", "剑", 20, 10, "无", v1Enchantments), 1);
    
    std::vector<std::string> v2Enchantments = {"高级锋利", "火焰"};
    versionManager.registerPrototype("magic_sword", 
        std::make_unique<MagicWeapon>("魔法剑v2", "剑", 25, 15, "火", v2Enchantments), 2);
    
    // 显示版本信息
    versionManager.displayVersionInfo("magic_sword");
    
    // 克隆不同版本
    auto v1Sword = versionManager.clonePrototype("magic_sword", 1);
    auto v2Sword = versionManager.clonePrototype("magic_sword", 2);
    auto currentSword = versionManager.clonePrototype("magic_sword");
    
    std::cout << "\n版本1武器:" << std::endl;
    if (v1Sword) v1Sword->display();
    
    std::cout << "\n版本2武器:" << std::endl;
    if (v2Sword) v2Sword->display();
    
    std::cout << "\n当前版本武器:" << std::endl;
    if (currentSword) currentSword->display();
    
    std::cout << "\n=== 原型模式测试结束 ===" << std::endl;
}

// 实战应用:游戏对象复制系统
class GameObjectDuplicationSystem {
private:
    AdvancedPrototypeManager manager_;
    
public:
    GameObjectDuplicationSystem() {
        setupPrototypes();
    }
    
    void setupPrototypes() {
        // 设置各种游戏对象原型
        std::vector<std::string> npcDialogs = {"你好,旅行者!", "需要帮助吗?", "小心前方的怪物!"};
        
        // 在实际游戏中,这些原型可以从配置文件加载
    }
    
    // 快速生成游戏场景
    void generateGameScene(const std::string& sceneType) {
        std::cout << "\n🎬 生成游戏场景: " << sceneType << std::endl;
        
        if (sceneType == "forest") {
            generateForestScene();
        } else if (sceneType == "dungeon") {
            generateDungeonScene();
        } else if (sceneType == "town") {
            generateTownScene();
        }
    }
    
private:
    void generateForestScene() {
        std::cout << "🌲 生成森林场景..." << std::endl;
        // 生成树木、动物、NPC等
        auto forestProps = manager_.cloneByCategory("forest_props");
        std::cout << "✅ 生成 " << forestProps.size() << " 个森林道具" << std::endl;
    }
    
    void generateDungeonScene() {
        std::cout << "🏰 生成地下城场景..." << std::endl;
        // 生成怪物、宝藏、陷阱等
        auto dungeonProps = manager_.cloneByCategory("dungeon_props");
        std::cout << "✅ 生成 " << dungeonProps.size() << " 个地下城道具" << std::endl;
    }
    
    void generateTownScene() {
        std::cout << "🏠 生成城镇场景..." << std::endl;
        // 生成NPC、建筑、商店等
        auto townProps = manager_.cloneByCategory("town_props");
        std::cout << "✅ 生成 " << townProps.size() << " 个城镇道具" << std::endl;
    }
};

int main() {
    testPrototypePattern();
    
    // 运行游戏对象复制系统示例
    std::cout << "\n🎮 游戏对象复制系统示例:" << std::endl;
    GameObjectDuplicationSystem gameSystem;
    gameSystem.generateGameScene("forest");
    gameSystem.generateGameScene("dungeon");
    gameSystem.generateGameScene("town");
    
    return 0;
}

原型模式的武学心得

适用场景
  • 创建成本高昂:当直接创建对象的成本较高时(如需要从数据库加载数据)
  • 避免重复初始化:当需要避免重复执行初始化代码时
  • 动态运行时创建:需要在运行时动态创建对象,但又不希望依赖具体的类
  • 保存对象状态:当需要保存对象的状态,并在需要时恢复
  • 快速对象生成:需要快速生成大量相似对象时
优点
  • 性能提升:通过克隆避免重复的初始化过程
  • 简化创建:隐藏对象创建的复杂性
  • 动态性:可以在运行时动态添加或删除原型
  • 减少子类:不需要为每种对象类型创建子类
  • 状态保存:可以保存和恢复对象状态
缺点
  • 克隆复杂性:实现深拷贝可能比较复杂
  • 循环引用:对象之间存在循环引用时,克隆需要特别处理
  • 破坏封装:可能需要访问类的私有成员来实现克隆
  • 内存开销:需要维护原型对象,增加内存使用

武林高手的点评

Builder 赞叹道:"Prototype 兄的克隆大法确实精妙!在需要快速创建相似对象时,这种方法确实比我的逐步构建更加高效。"

Abstract Factory 也点头称赞:"Prototype 兄的方法在对象创建成本高昂时特别有用。我的抽象工厂需要知道所有产品类型,而原型模式可以在运行时动态添加新类型。"

Prototype 谦虚回应:"诸位过奖了。每个模式都有其适用场景。在需要快速创建相似对象且创建成本较高时,我的原型模式确实能发挥重要作用。但在需要精确控制构建过程时,Builder 兄的方法更加合适。"

下章预告

在Prototype展示完他的克隆大法后,Adapter 忙碌地走出,他身上挂着的各种转接头叮当作响。

"Prototype 兄的克隆确实高效,但在软件江湖中,我们常常需要让不兼容的接口能够协同工作。" Adapter 笑着说道,"下一章,我将展示如何通过适配器模式让原本接口不兼容的类能够一起工作!"

架构老人满意地点头:"善!接口的兼容确实是软件集成中的重要问题。下一章,就请 Adapter 展示他的转接艺术!"


欲知 Adapter 如何通过适配器模式解决接口不兼容问题,且听下回分解!

相关推荐
从前慢,现在也慢2 小时前
【STL学习】(9)priority_queue
c++·学习
序属秋秋秋2 小时前
《C++进阶之C++11》【智能指针】(上)
c++·笔记·学习·面试·c++11·智能指针·新特性
white-persist2 小时前
【burp手机真机抓包】Burp Suite 在真机(Android and IOS)抓包手机APP + 微信小程序详细教程
android·前端·ios·智能手机·微信小程序·小程序·原型模式
guigu20122 小时前
C++ STL 深度解析:容器、迭代器与算法的协同作战
c++·嵌入式编程
Yupureki2 小时前
从零开始的C++学习生活 3:类和对象(中)
c语言·c++·学习·visual studio
1710orange4 小时前
java设计模式:静态代理模式
java·设计模式·代理模式
凤年徐4 小时前
【C++】string类
c语言·开发语言·c++
我真的是大笨蛋4 小时前
开闭原则详解(OCP)
java·设计模式·性能优化·开闭原则·设计规范
ajassi20004 小时前
开源 C++ QT QML 开发(五)复杂控件--Gridview
c++·qt·开源