第五章:原型模式 - 克隆大法的大师
故事延续:幻影分身的奇妙艺术
在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 如何通过适配器模式解决接口不兼容问题,且听下回分解!