工厂模式详细讲解

一、工厂模式的定位

工厂模式是创建型设计模式的核心,核心思想是将对象的创建与使用分离:把对象创建的复杂逻辑封装在"工厂类"中,业务代码(调用方)只需通过工厂获取对象,无需关注对象的实例化细节(如构造函数参数、子类选择等)。它主要解决了"直接new对象导致的代码耦合、扩展困难"问题,同时让代码更符合开闭原则和单一职责原则。主要分为简单工厂、工厂方法、抽象工厂三种形式,适配不同的业务场景。

二、分类讲解

  1. 简单工厂
  • 定义:由一个单一的工厂类,根据传入的参数动态创建对应产品实例(不属于GoF官方23种设计模式,是工厂方法的简化版)。
  • 举例:RPG游戏中,用 SimpleCharacterFactory 接收 "warrior" / "mage" 参数,内部通过 switch 判断,分别创建 Warrior / Mage 对象。
  • 优点:简化对象创建,调用方只需传参;缺点:新增角色(如弓箭手)需修改工厂类的 switch 逻辑,违反开闭原则,仅适合产品类型少且变动少的场景。
  1. 工厂方法
  • 定义:定义抽象工厂接口,让具体工厂子类决定实例化哪个产品类,把对象实例化延迟到子类。
  • 举例:先定义抽象工厂 CharacterFactory ,再为战士、法师分别创建 WarriorFactory 、 MageFactory 子类,每个子类重写 createCharacter 方法创建对应角色。
  • 优点:新增角色只需加产品类和对应工厂子类,无需改原有代码,符合开闭原则;缺点:产品和工厂一一对应,产品过多时会产生大量工厂类,增加代码复杂度。
  1. 抽象工厂
  • 定义:创建相关/依赖的产品族,而非单一产品,接口中定义多个产品的创建方法。
  • 举例:RPG游戏中,"角色+武器"是产品族: HumanFactory 创建人类战士+人类剑, ElfFactory 创建精灵弓箭手+精灵弓,抽象工厂 RaceFactory 定义 createCharacter 和 createWeapon 两个接口。
  • 优点:保证产品族内对象的兼容性;缺点:新增产品(如防具)需修改抽象工厂接口,所有具体工厂都要同步修改,扩展成本高。

三种工厂模式对比表

模式类型 工厂类特点 产品创建逻辑 开闭原则兼容性
简单工厂 单一工厂类,静态方法 工厂内部判断参数 不兼容
工厂方法 抽象工厂+多个具体工厂子类 子类实现创建逻辑 兼容
抽象工厂 抽象工厂+产品族工厂子类 子类创建产品族 产品族扩展兼容

三、代码实现(三种工厂模式)

cpp 复制代码
#include<iostream>
#include<memory>
#include<string>
using namespace std;

class Character{
protected:
    string name;
    int health;
    int attack;
    int magic;

public:
    Character(const string& n,int h,int a,int m )
    :name(n),health(h),attack(a),magic(m){}

    virtual ~Character()=default;

    virtual void showInfo() const{
        cout<<"角色:"<<name<<endl;
        cout<<"血量:"<<health<<endl;
        cout<<"攻击力:"<<attack<<endl;
        cout<<"魔力:"<<magic<<endl;
    }
    virtual void specialSkill()=0;

    string getName() const{return name;}
};

//具体角色类 - 战士
class Warrior : public Character{
public:
    Warrior(const string& name):Character(name,150,80,20){}

    void specialSkill()override{
        cout<<name<<"使用【狂暴攻击】!"<<endl;
    }
    
    void showInfo()const override{
        cout<<"=== 战士 ==="<<endl;
        Character::showInfo();
        cout<<"特长:近战攻击,高血量"<<endl;
    }
};

//具体角色类 - 法师
class Mage : public Character{
public:
    Mage(const string& name):Character(name,80,30,120){}

    void specialSkill()override{
        cout<<name<<"释放【豪火球】!"<<endl;
    }

    void showInfo()const override{
        cout<<"=== 法师 ==="<<endl;
        Character::showInfo();
        cout<<"特长:魔法攻击,高魔力"<<endl;
    }
};

//具体角色类 - 弓箭手
class Archer : public Character{
public:
    Archer(const string& name):Character(name,100,70,50){}

    void specialSkill()override{
        cout<<name<<"使用【穿透射击】!"<<endl;
    }

    void showInfo()const override{
        cout<<"=== 弓箭手 ==="<<endl;
        Character::showInfo();
        cout<<"特长:远程攻击,平衡属性"<<endl;
    }
};

/****************************简单工厂***************************/
enum CharacterType{
    WARRIOR,
    MAGE,
    ARCHER,
};

class SimpleCharacterFactory{
public:
    static unique_ptr<Character>
    CreateCharacter(CharacterType type,const string &name){
        switch(type){
        case WARRIOR:
            return make_unique<Warrior>(name);
        case MAGE:
            return make_unique<Mage>(name);
        case ARCHER:
            return make_unique<Archer>(name);
        default:
        throw invalid_argument("未知的角色类型");
        }
    }
};

/*******************************工厂方法*******************************/
class CharacterFactory{
protected:
    virtual void setupCharacter(Character* character){
        cout<<"角色"<<character->getName()<<"创建完成,进行基础设置..."<<endl;
    }
public:
    virtual ~CharacterFactory()= default;
    virtual unique_ptr<Character> createCharacter(const string &name) = 0;

    unique_ptr<Character> createCharacterWithSetup(const string &name){
        auto character=createCharacter(name);
        setupCharacter(character.get());
        return character;
    }
};

class WarriorFactory : public CharacterFactory{
protected:
    virtual void setupCharacter(Character* character){
        CharacterFactory::setupCharacter(character);
        cout<<"为战士配备铁剑和盾牌..."<<endl;
    }
public:
    virtual unique_ptr<Character> createCharacter(const string &name){
        return make_unique<Warrior>(name);
    }
};

class MageFactory : public CharacterFactory{
protected:
    virtual void setupCharacter(Character* character){
        CharacterFactory::setupCharacter(character);
        cout<<"为法师配备魔法书和法杖..."<<endl;
    }
public:
    virtual unique_ptr<Character> createCharacter(const string &name){
        return make_unique<Mage>(name);
    }
};

class ArcherFactory : public CharacterFactory{
protected:
    virtual void setupCharacter(Character* character){
        CharacterFactory::setupCharacter(character);
        cout<<"为弓箭手配备弓箭和箭筒..."<<endl;
    }
public:
    virtual unique_ptr<Character> createCharacter(const string &name){
        return make_unique<Archer>(name);
    }
};

/********************************抽象工厂*****************************/
//抽象装备类
class Equipment{
public:
    virtual ~Equipment() = default;
    virtual string getDescription() const = 0;
};

//具体装备类
class HumanSword : public Equipment{
public:
    string getDescription() const override{
        return "人族青钢剑";
    }
};

class HumanShield : public Equipment{
public:
    string getDescription() const override{
        return "人类骑士盾";
    }
};

class ElfBow : public Equipment{
public:
    string getDescription()const override{
        return "精灵月光弓";
    }
};

class ElfCloak : public Equipment{
public:
    string getDescription() const override{
        return "精灵隐身斗篷";
    }
};

//抽象工厂 - 种族工厂
class RaceFactory{
public:
    virtual ~RaceFactory()=default;
    virtual unique_ptr<Character> createWarrior(const string& name) = 0;
    virtual unique_ptr<Character> createArcher(const string& name) = 0;
    virtual unique_ptr<Equipment> createWeapon() = 0;
    virtual unique_ptr<Equipment> createArmor() = 0;
    virtual string getRaceName() const = 0;
};

//具体种族角色类
class HumanWarrior : public Warrior{
public:
    HumanWarrior(const string& name):Warrior(name+"(人族)"){}

    void showInfo() const override{
        cout<<"=== 人族战士 ==="<<endl;
        Character::showInfo();
        cout<<"特长:均衡发展,适应力强"<<endl;
    }
};

class ElfArcher : public Archer{
public:
    ElfArcher(const string& name):Archer(name+"(精灵)"){}

    void showInfo() const override{
        cout<<"=== 精灵弓箭手 ==="<<endl;
        Character::showInfo();
        cout<<"特长:敏捷过人,箭术精悍"<<endl;
    }
};

//具体工厂类 - 人族工厂
class HumanFactory : public RaceFactory{
public:
    unique_ptr<Character> createWarrior(const string& name)override{
        return make_unique<HumanWarrior>(name);
    }

    unique_ptr<Character> createArcher(const string& name)override{
        return make_unique<Archer>(name+"(人族)");
    }

    unique_ptr<Equipment> createWeapon()override{
        return make_unique<HumanSword>();
    }

    unique_ptr<Equipment> createArmor()override{
        return make_unique<HumanShield>();
    }

    string getRaceName() const override{
        return "人族";
    }
};

//具体工厂类 - 精灵工厂
class ElfFactory : public RaceFactory{
public:
    unique_ptr<Character> createWarrior(const string& name)override{
        return make_unique<Warrior>(name);
    }

    unique_ptr<Character> createArcher(const string& name)override{
        return make_unique<ElfArcher>(name+"(精灵)");
    }

    unique_ptr<Equipment> createWeapon()override{
        return make_unique<ElfBow>();
    }

    unique_ptr<Equipment> createArmor()override{
        return make_unique<ElfCloak>();
    }

    string getRaceName() const override{
        return "精灵";
    }
};

int main()
{
    cout<<"=== 工厂模式对比演示 ==="<<endl;

    cout<<"\n1.简单工厂 - 集中式创建:"<<endl;
    cout<<"优点:实现简单,使用方便"<<endl;
    cout<<"缺点:违反开闭原则,拓展需要修改工厂类"<<endl;
    auto simpleWarrior=SimpleCharacterFactory::CreateCharacter(CharacterType::WARRIOR,"简单战士");
    cout<<"创建结果:"<<simpleWarrior->getName()<<endl;

    cout<<"\n2.工厂方法 - 多态创建:"<<endl;
    cout<<"优点:符合开闭原则,易于扩展"<<endl;
    cout<<"缺点:需要创建多个工厂类"<<endl;
    auto methodFactory = make_unique<WarriorFactory>();
    auto methodWarrior = methodFactory->createCharacterWithSetup("方法战士");
    cout<<"创建结果:"<<methodWarrior->getName()<<endl;

    cout<<"\n3.抽象工厂 - 产品族创建:"<<endl;
    cout<<"优点:可以创建相关产品族,保证产品兼容性"<<endl;
    cout<<"缺点:扩展产品族较困难"<<endl;
    auto abstractFactory = make_unique<HumanFactory>();
    auto abstractWarrior = abstractFactory->createWarrior("抽象战士");
    auto abstractWeapon = abstractFactory->createWeapon();
    cout<<"创建结果:"<<abstractWarrior->getName()<<" + "<<abstractWeapon->getDescription()<<endl;
    return 0;
}

运行结果:

相关推荐
码农小卡拉2 小时前
数据库:主键 VS 唯一索引 区别详解
java·数据库·sql
廋到被风吹走2 小时前
【数据库】【MySQL】锁机制深度解析:从原理到死锁分析实战
数据库·mysql
_OP_CHEN2 小时前
【从零开始的Qt开发指南】(二十三)Qt 界面优化之 QSS 实战指南:从入门到精通,让你的界面颜值飙升!
开发语言·c++·qt·前端开发·界面美化·qss·客户端开发
海棠AI实验室2 小时前
第 3 篇:方案写作——SOW / 里程碑 / 验收标准 / 风险假设的标准模板
数据库·python
HellowAmy2 小时前
我的C++规范 - 跳跃的对象
开发语言·c++·代码规范
lucky-billy2 小时前
架构设计 - std::forward 条件转换配合万能引用(T&&)来实现完美转发
c++·完美转发·forward·万能引用
阿坤带你走近大数据3 小时前
ORACLE里length和lengthb函数的异同点分别是
数据库·oracle
航Hang*3 小时前
第3章:复习篇——第1节:创建和管理数据库---题库
数据库·笔记·sql·学习·期末·复习
bkspiderx3 小时前
C/C++中float浮点型的存储方式与使用要点
c++