第二章:工厂方法模式 - 创造之道的灵活变通
第二章:工厂方法模式 - 创造之道的灵活变通
故事延续:工匠的创造艺术
在Singleton展示完他那孤高的剑法后,Factory Method 缓步走出,他腰间工具碰撞的清脆声响吸引了所有人的注意。这位身着粗布工匠服的大师,眼中闪烁着智慧的光芒。
“Singleton 兄的’唯一之道’确实精妙,” Factory Method 微笑着向Singleton点头致意,“但软件江湖中,更多时候我们需要的是’灵活创造’的能力。我的武学核心在于——定义一个创建对象的接口,但让子类决定实例化哪个具体类。”
工厂方法模式的武学精要
核心心法
Factory Method双手结印,空中浮现出抽象的创建蓝图:“我的八字真言是——延迟实例化到子类。通过将对象的创建过程封装在工厂方法中,让子类来决定具体创建什么对象,实现了创建逻辑与使用逻辑的完美分离。”
C++ 代码实战
#include <iostream>
#include <memory>
#include <string>
#include <vector>// 产品接口:武林兵器
class Weapon {
public:virtual ~Weapon() = default;virtual void attack() const = 0;virtual std::string getName() const = 0;virtual int getDamage() const = 0;
};// 具体产品:长剑
class LongSword : public Weapon {
public:void attack() const override {std::cout << "⚔️ 长剑挥舞,寒光一闪!" << std::endl;}std::string getName() const override {return "精钢长剑";}int getDamage() const override {return 15;}
};// 具体产品:弓箭
class Bow : public Weapon {
public:void attack() const override {std::cout << "🏹 弓弦震动,箭如流星!" << std::endl;}std::string getName() const override {return "硬木长弓";}int getDamage() const override {return 12;}
};// 具体产品:法杖
class Staff : public Weapon {
public:void attack() const override {std::cout << "🔮 法杖挥舞,元素汇聚!" << std::endl;}std::string getName() const override {return "橡木法杖";}int getDamage() const override {return 18;}
};// 创建者抽象类:兵器匠人
class Blacksmith {
public:virtual ~Blacksmith() = default;// 工厂方法:创建兵器virtual std::unique_ptr<Weapon> createWeapon() const = 0;// 模板方法:打造兵器的完整流程void forgeWeapon() const {std::cout << "🔥 开始打造兵器..." << std::endl;auto weapon = createWeapon();std::cout << "✅ 成功打造出: " << weapon->getName() << " | 伤害: " << weapon->getDamage() << std::endl;weapon->attack();}// 批量生产std::vector<std::unique_ptr<Weapon>> massProduction(int count) const {std::vector<std::unique_ptr<Weapon>> weapons;for (int i = 0; i < count; ++i) {weapons.push_back(createWeapon());}return weapons;}
};// 具体创建者:剑匠
class SwordSmith : public Blacksmith {
public:std::unique_ptr<Weapon> createWeapon() const override {return std::make_unique<LongSword>();}
};// 具体创建者:弓匠
class BowSmith : public Blacksmith {
public:std::unique_ptr<Weapon> createWeapon() const override {return std::make_unique<Bow>();}
};// 具体创建者:法杖匠人
class StaffSmith : public Blacksmith {
public:std::unique_ptr<Weapon> createWeapon() const override {return std::make_unique<Staff>();}
};
UML 武功秘籍图
实战演练:游戏中的角色创建系统
#include <random>
#include <map>// 更复杂的游戏角色系统
class Character {
public:virtual ~Character() = default;virtual void display() const = 0;virtual void specialAbility() const = 0;virtual std::string getType() const = 0;virtual int getHealth() const = 0;virtual int getMana() const = 0;
};// 具体角色:战士
class Warrior : public Character {
public:void display() const override {std::cout << "🛡️ 战士 - 高生命值,近战专家" << std::endl;}void specialAbility() const override {std::cout << "💥 发动技能:旋风斩!" << std::endl;}std::string getType() const override {return "战士";}int getHealth() const override {return 150;}int getMana() const override {return 50;}
};// 具体角色:法师
class Mage : public Character {
public:void display() const override {std::cout << "🧙 法师 - 强大魔法,远程攻击" << std::endl;}void specialAbility() const override {std::cout << "🔥 发动技能:火球术!" << std::endl;}std::string getType() const override {return "法师";}int getHealth() const override {return 80;}int getMana() const override {return 120;}
};// 具体角色:游侠
class Ranger : public Character {
public:void display() const override {std::cout << "🏹 游侠 - 敏捷身手,远程专家" << std::endl;}void specialAbility() const override {std::cout << "🎯 发动技能:多重射击!" << std::endl;}std::string getType() const override {return "游侠";}int getHealth() const override {return 100;}int getMana() const override {return 80;}
};// 角色创建工厂
class CharacterFactory {
public:virtual ~CharacterFactory() = default;virtual std::unique_ptr<Character> createCharacter() const = 0;virtual std::string getFactoryName() const = 0;void createAndDisplay() const {auto character = createCharacter();std::cout << "\n🎭 创建角色: " << character->getType() << std::endl;character->display();std::cout << "❤️ 生命值: " << character->getHealth() << " | 🔮 法力值: " << character->getMana() << std::endl;character->specialAbility();}
};// 具体角色工厂
class WarriorFactory : public CharacterFactory {
public:std::unique_ptr<Character> createCharacter() const override {return std::make_unique<Warrior>();}std::string getFactoryName() const override {return "战士训练营";}
};class MageFactory : public CharacterFactory {
public:std::unique_ptr<Character> createCharacter() const override {return std::make_unique<Mage>();}std::string getFactoryName() const override {return "魔法学院";}
};class RangerFactory : public CharacterFactory {
public:std::unique_ptr<Character> createCharacter() const override {return std::make_unique<Ranger>();}std::string getFactoryName() const override {return "游侠营地";}
};// 随机角色工厂
class RandomCharacterFactory : public CharacterFactory {
private:mutable std::random_device rd;mutable std::mt19937 gen;std::uniform_int_distribution<> dis;public:RandomCharacterFactory() : gen(rd()), dis(0, 2) {}std::unique_ptr<Character> createCharacter() const override {int choice = dis(gen);switch (choice) {case 0: return std::make_unique<Warrior>();case 1: return std::make_unique<Mage>();case 2: return std::make_unique<Ranger>();default: return std::make_unique<Warrior>();}}std::string getFactoryName() const override {return "随机角色生成器";}
};
工厂方法的招式解析
招式一:参数化工厂方法
// 通过参数决定创建哪种产品
class FlexibleWeaponSmith : public Blacksmith {
public:enum WeaponType { SWORD, BOW, STAFF };std::unique_ptr<Weapon> createWeapon(WeaponType type) const {switch (type) {case SWORD: return std::make_unique<LongSword>();case BOW: return std::make_unique<Bow>();case STAFF: return std::make_unique<Staff>();default: return nullptr;}}// 仍然实现抽象接口std::unique_ptr<Weapon> createWeapon() const override {return createWeapon(SWORD); // 默认创建剑}
};
招式二:带配置的工厂
// 可配置的武器工厂
class ConfigurableWeaponFactory {
private:struct WeaponConfig {std::string name;int baseDamage;std::string attackSound;};std::map<std::string, WeaponConfig> configurations;public:ConfigurableWeaponFactory() {// 预定义配置configurations["basic_sword"] = {"训练用剑", 8, "挥舞训练剑!"};configurations["iron_sword"] = {"铁剑", 15, "铁剑劈砍!"};configurations["steel_bow"] = {"钢弓", 12, "钢弓射击!"};}std::unique_ptr<Weapon> createWeapon(const std::string& configName) const {auto it = configurations.find(configName);if (it != configurations.end()) {// 返回配置化的武器return createCustomWeapon(it->second);}return nullptr;}private:std::unique_ptr<Weapon> createCustomWeapon(const WeaponConfig& config) const {// 创建自定义武器(这里简化实现)class CustomWeapon : public Weapon {WeaponConfig config_;public:CustomWeapon(WeaponConfig config) : config_(std::move(config)) {}void attack() const override {std::cout << config_.attackSound << std::endl;}std::string getName() const override {return config_.name;}int getDamage() const override {return config_.baseDamage;}};return std::make_unique<CustomWeapon>(config);}
};
完整测试代码
// 测试工厂方法模式
void testFactoryMethodPattern() {std::cout << "=== 工厂方法模式测试开始 ===" << std::endl;// 测试兵器系统std::cout << "\n--- 兵器打造系统测试 ---" << std::endl;SwordSmith swordSmith;BowSmith bowSmith;StaffSmith staffSmith;swordSmith.forgeWeapon();bowSmith.forgeWeapon();staffSmith.forgeWeapon();// 测试批量生产std::cout << "\n--- 批量生产测试 ---" << std::endl;auto swords = swordSmith.massProduction(3);std::cout << "批量生产了 " << swords.size() << " 把剑" << std::endl;// 测试角色创建系统std::cout << "\n--- 角色创建系统测试 ---" << std::endl;WarriorFactory warriorFactory;MageFactory mageFactory;RangerFactory rangerFactory;RandomCharacterFactory randomFactory;warriorFactory.createAndDisplay();mageFactory.createAndDisplay();rangerFactory.createAndDisplay();std::cout << "\n--- 随机角色生成 ---" << std::endl;for (int i = 0; i < 3; ++i) {randomFactory.createAndDisplay();}// 测试参数化工厂std::cout << "\n--- 参数化工厂测试 ---" << std::endl;FlexibleWeaponSmith flexibleSmith;auto weapon1 = flexibleSmith.createWeapon(FlexibleWeaponSmith::BOW);auto weapon2 = flexibleSmith.createWeapon(FlexibleWeaponSmith::STAFF);std::cout << "参数化创建: " << weapon1->getName() << std::endl;std::cout << "参数化创建: " << weapon2->getName() << std::endl;// 测试配置化工厂std::cout << "\n--- 配置化工厂测试 ---" << std::endl;ConfigurableWeaponFactory configFactory;auto customWeapon = configFactory.createWeapon("iron_sword");if (customWeapon) {std::cout << "配置化创建: " << customWeapon->getName() << std::endl;customWeapon->attack();}std::cout << "\n=== 工厂方法模式测试结束 ===" << std::endl;
}// 实战应用示例
class GameApplication {
private:std::vector<std::unique_ptr<CharacterFactory>> factories;public:GameApplication() {// 注册所有可用的角色工厂factories.push_back(std::make_unique<WarriorFactory>());factories.push_back(std::make_unique<MageFactory>());factories.push_back(std::make_unique<RangerFactory>());factories.push_back(std::make_unique<RandomCharacterFactory>());}void run() {std::cout << "\n🎮 游戏角色创建系统启动!" << std::endl;for (const auto& factory : factories) {std::cout << "\n🏭 使用工厂: " << factory->getFactoryName() << std::endl;factory->createAndDisplay();}// 创建一支冒险队伍std::cout << "\n👥 创建冒险队伍..." << std::endl;std::vector<std::unique_ptr<Character>> party;for (int i = 0; i < 4; ++i) {RandomCharacterFactory randomFactory;party.push_back(randomFactory.createCharacter());}std::cout << "🚀 冒险队伍组建完成!共有 " << party.size() << " 名成员" << std::endl;}
};int main() {testFactoryMethodPattern();// 运行游戏应用示例GameApplication game;game.run();return 0;
}
工厂方法模式的武学心得
适用场景
- 框架设计:让框架定义接口,具体实现由应用决定
- 类库设计:让使用者扩展功能而不修改库代码
- 对象创建需要灵活性:运行时决定创建哪种对象
- 解耦创建逻辑:将产品创建与使用分离
优点
- 符合开闭原则:添加新产品时无需修改现有代码
- 解耦性强:客户端代码与具体产品类解耦
- 可扩展性好:很容易添加新的产品类型
- 符合单一职责原则:创建逻辑集中在工厂类中
缺点
- 类数量增加:每个具体产品都需要对应的工厂类
- 复杂度增加:对于简单场景可能过于复杂
- 需要继承:必须通过子类化来创建对象
武林高手的点评
Abstract Factory 抚须微笑:“徒儿,你这工厂方法确实精妙!将创建逻辑延迟到子类,让系统更加灵活。不过,当需要创建一系列相关产品时,就需要为师出马了。”
Factory Method 恭敬行礼:“师父所言极是。工厂方法适用于单一产品的创建,而师父的抽象工厂模式则擅长处理产品家族的创建,各有千秋。”
Singleton 也点头称赞:“Factory Method 兄的创造之道确实灵活多变,不像我那’唯一存在’的限制。在需要多样化的场景下,你的方法确实更加适用。”
下章预告
在Factory Method展示完他的创造艺术后,Abstract Factory 大步走出,他身后的产品家族方阵气势恢宏。
“徒儿的工厂方法确实灵活,但现实世界中,我们往往需要创建的是相互关联的整套产品。” Abstract Factory 声音洪亮,“下一章,我将展示如何创建整个产品家族,确保产品之间的兼容性!让界面组件、游戏套装、数据库连接这些相关产品能够完美配合!”
架构老人眼中闪过赞许的光芒:“善!产品家族的创建确实需要更高层次的抽象。下一章,就请 Abstract Factory 展示他的家族创造之道!”
欲知 Abstract Factory 如何通过抽象工厂模式创建完整产品家族,且听下回分解!