1. 设计模式演进:从简单工厂到抽象工厂
在软件开发中,创建对象是最基础也最频繁的操作之一。随着系统复杂度提升,直接使用new关键字实例化对象会带来诸多问题:代码耦合度高、难以扩展、违反开闭原则等。设计模式中的工厂系列正是为解决这些问题而生的。
1.1 简单工厂模式:入门级解决方案
简单工厂模式是最基础的对象创建方式,它通过一个工厂类中的条件判断来决定创建哪种具体产品。让我们看一个水果工厂的例子:
cpp复制class Fruit {
public:
virtual void eat() = 0;
virtual ~Fruit() {} // 基类虚析构函数很重要
};
class Apple : public Fruit {
public:
void eat() override {
cout << "咬下一口脆甜的苹果" << endl;
}
};
class Banana : public Fruit {
public:
void eat() override {
cout << "剥开香蕉皮享用" << endl;
}
};
class FruitFactory {
public:
static Fruit* createFruit(const string& type) {
if (type == "apple") return new Apple();
if (type == "banana") return new Banana();
throw runtime_error("不支持的水果类型"); // 比返回nullptr更安全
}
};
使用简单工厂的优势在于:
- 将对象创建逻辑集中管理
- 客户端代码与具体产品类解耦
- 统一了对象的创建入口
但简单工厂有明显的局限性:
- 工厂类职责过重,违反单一职责原则
- 新增产品类型需要修改工厂类,违反开闭原则
- 条件判断随着产品增多会变得臃肿
提示:在实际项目中,简单工厂适合产品类型固定、变化少的场景。如果预期产品会频繁扩展,建议考虑更灵活的模式。
1.2 工厂方法模式:多态化的工厂
工厂方法模式通过引入抽象工厂类和具体工厂子类来解决简单工厂的问题。每个具体工厂只负责创建一种产品:
cpp复制class FruitFactory {
public:
virtual Fruit* createFruit() = 0;
virtual ~FruitFactory() {} // 基类虚析构不可少
};
class AppleFactory : public FruitFactory {
public:
Fruit* createFruit() override {
return new Apple();
}
};
class BananaFactory : public FruitFactory {
public:
Fruit* createFruit() override {
return new Banana();
}
};
工厂方法的优势:
- 符合开闭原则,新增产品只需添加新工厂类
- 每个工厂类职责单一
- 多态特性使得客户端代码更灵活
但工厂方法也有其适用场景的局限性:
- 每个产品都需要对应一个工厂类,类数量膨胀
- 适合创建单一产品,难以处理相关产品族的创建
1.3 何时需要抽象工厂
当系统需要创建一组相关或依赖的对象时,工厂方法就显得力不从心了。例如:
- 开发跨平台UI组件库,需要保证按钮、文本框等风格一致
- 游戏中的角色装备系统,需要武器、防具等风格匹配
- 家具系统中的成套家具创建
这类场景下,抽象工厂模式就派上用场了。它能够确保创建的对象是相互关联或依赖的,保持产品族的一致性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 抽象工厂模式深度解析
2.1 模式结构与核心组件
抽象工厂模式包含以下关键角色:
- 抽象产品(Abstract Product):定义产品对象的接口
- 具体产品(Concrete Product):实现抽象产品接口的具体类
- 抽象工厂(Abstract Factory):声明创建抽象产品对象的接口
- 具体工厂(Concrete Factory):实现抽象工厂的接口,创建具体产品
以家具系统为例,我们来看具体实现:
cpp复制// 抽象产品:桌子
class Table {
public:
virtual void display() = 0;
virtual ~Table() {}
};
// 抽象产品:椅子
class Chair {
public:
virtual void sit() = 0;
virtual ~Chair() {}
};
// 中式具体产品
class C
