定义与概念
抽象工厂模式是一种创建型设计模式。它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。简单来说,抽象工厂就像是一个工厂的抽象蓝图,这个蓝图定义了生产一组产品的方法,但具体怎么生产这些产品(产品的具体实现)由具体的工厂类来完成。
模式结构
- 抽象工厂类(Abstract Factory):
这是一个抽象类,它声明了创建一系列产品对象的抽象方法。例如,在一个游戏开发场景中,抽象工厂类可能有创建游戏角色、游戏场景道具等抽象方法。 - 具体工厂类(Concrete Factory):
实现了抽象工厂类中声明的抽象方法,用于创建具体的产品对象。每个具体工厂类负责创建一组相关的产品。比如,一个 “中世纪游戏工厂” 具体工厂类可以创建中世纪风格的游戏角色和道具;而一个 “科幻游戏工厂” 具体工厂类则创建科幻风格的相应产品。 - 抽象产品类(Abstract Product):
这也是抽象类,它为具体产品类定义了接口。在游戏示例中,抽象产品类可以是游戏角色抽象类,定义了游戏角色的基本行为和属性接口,如移动、攻击等。 - 具体产品类(Concrete Product):
实现了抽象产品类的接口,是抽象产品类的具体实现。例如,“中世纪骑士角色” 类和 “科幻机器人角色” 类分别是游戏角色抽象产品类的具体实现,它们有自己特定的移动和攻击方式等属性。
代码示例
假设我们要创建一个简单的图形绘制系统,有两种风格的图形:简约风格和华丽风格。
- 首先是抽象产品类:
// 抽象图形类
class Shape {
public:virtual void draw() = 0;
};
- 然后是具体产品类,以圆形为例:
- 简约风格圆形:
class SimpleCircle : public Shape { public:void draw() override {std::cout << "Drawing a simple circle." << std::endl;} };
- 华丽风格圆形:
class FancyCircle : public Shape { public:void draw() override {std::cout << "Drawing a fancy circle." << std::endl;} };
- 简约风格圆形:
- 接着是抽象工厂类:
class ShapeFactory {
public:virtual Shape* createCircle() = 0;
};
-
最后是具体工厂类:
-
简约风格工厂:
class SimpleShapeFactory : public ShapeFactory { public:Shape* createCircle() override {return new SimpleCircle();} };
-
华丽风格工厂:
class FancyShapeFactory : public ShapeFactory { public:Shape* createCircle() override {return new FancyCircle();} };
-
-
使用:
int main() {ShapeFactory* factory = new SimpleShapeFactory();Shape* circle = factory->createCircle();circle->draw();delete circle;delete factory;return 0;
}
这段代码输出了绘制简约风格圆形的信息。如果我们想要绘制华丽风格的圆形,只需要将SimpleShapeFactory替换为FancyShapeFactory即可。
优点
- 可维护性高:
当需要增加新的产品系列或者修改产品的创建逻辑时,只需要修改具体的工厂类和产品类,不需要在大量的代码中去寻找和修改创建对象的地方。例如,在图形绘制系统中,如果要增加一种新的图形风格,只需要创建新的工厂类和对应的产品类,不会影响到已经存在的其他风格的代码。 - 可扩展性强:
易于添加新的产品族。比如在游戏开发中,要添加一个新的游戏风格(如神话风格),可以很方便地创建神话风格的工厂类和相应的产品类来生成神话风格的游戏角色和道具。 - 产品对象的使用和创建分离:
客户端代码只需要通过抽象工厂类来获取产品对象,不需要知道产品对象的具体创建过程。这使得代码的耦合度降低,客户端代码更加简洁。
缺点
- 代码复杂:
由于抽象工厂模式涉及到多个抽象类和具体类的层次结构,代码相对复杂。对于简单的应用场景可能会增加不必要的复杂性。 - 不适合简单的产品创建:
如果系统只需要创建一种产品,或者产品之间的关联性不强,使用抽象工厂模式可能会显得有些过度设计。
适用场景
- 对象创建过程复杂:
当对象的创建过程涉及到多个步骤或者复杂的配置时,抽象工厂模式可以将这些复杂的创建过程封装在具体工厂类中。例如,在创建数据库连接对象时,可能需要配置各种参数,抽象工厂模式可以很好地封装这些配置过程。 - 需要创建一组相关对象:
在游戏开发、图形界面开发等领域,经常需要创建一组相关的对象。比如一个游戏场景需要同时创建游戏角色、游戏道具和游戏背景等相关对象,抽象工厂模式可以方便地实现这一功能。