一、工厂模式的定义与应用场景
定义与原理
工厂模式通过将对象的创建过程从使用端分离,为不同的实现提供统一的创建入口。核心思想是把对象构造委托给专门的工厂,以实现客户端代码对具体类的解耦。
在 C++ 的实现中,工厂通常通过静态工厂方法、工厂方法或抽象工厂来完成。解耦与扩展性是设计的关键目标,便于后续扩展新的产品线而不修改调用方代码。
应用场景概览
常见的使用场景包括插件化架构、跨平台组件、以及需要根据运行时条件选择不同实现的场景。通过工厂模式,系统可以在运行时替换具体产品而不影响调用方。运行时灵活性是这类模式的显著优势。
此外,工厂模式还能结合策略模式、模板方法模式等实现更强的可扩展性。组合使用有助于构建高内聚、低耦合的设计。
二、对象创建封装的设计要点
接口解耦与扩展性
通过定义纯虚接口(抽象产品),客户端只依赖于抽象,避免直接引用具体实现。依赖倒置原则在此处得到体现,允许新实现无缝接入。
工厂提供的入口点也应指向抽象工厂或接口,使得添加新实现无需修改调用方代码,从而提高系统的可扩展性。
生命周期与资源管理
对象的生命周期通常通过智能指针管理,如 std::unique_ptr 或 std::shared_ptr,避免裸指针带来的内存管理风险。
在多态对象的场景下,确保基类具有虚析构函数,以防止资源泄漏。正确的析构机制是安全的资源回收基础。
三、C++ 实现方式的对比与采用场景
简单工厂实现要点
简单工厂将对象创建逻辑集中在一个类中,调用端通过传入参数类型来获得具体实例。实现简单、易于理解,但对扩展性有一定约束。
该模式适用于产品族较少、变化不频繁的场景。初期开发成本低,便于快速落地。
// Simple Factory 示例
#include
#include
#include class Product {
public:virtual void info() const = 0;virtual ~Product() {}
};class ProductA : public Product {
public:void info() const override { std::cout << "ProductA" << std::endl; }
};class ProductB : public Product {
public:void info() const override { std::cout << "ProductB" << std::endl; }
};class SimpleFactory {
public:static std::unique_ptr createProduct(const std::string& type) {if (type == "A") return std::make_unique();if (type == "B") return std::make_unique();return nullptr;}
};// Usage
int main() {auto p = SimpleFactory::createProduct("A");if (p) p->info();return 0;
}
工厂方法与抽象工厂的对比
工厂方法通过将对象创建推迟到子类实现,支持多态扩展。扩展点在于子类实现,无需修改基类。对于产品家族的不同实现,抽象工厂提供一致的创建入口。统一的产品族接口有助于在多个产品之间保持一致性。
在设计上,工厂方法更适合简单场景,抽象工厂用于需要维护多个相关产品族的复杂场景。架构清晰度在大型系统中尤为重要。
四、实战示例:一个可扩展的图形对象工厂
需求分析与设计
需要一个可扩展的图形对象工厂来创建不同形状对象(如圆形、方形、三角形等)。目标是封装创建逻辑,让客户端仅关注绘制行为而非具体实现。
设计应满足:可扩展性、类型安全、资源管理与易用性,并尽量避免对已有代码的侵入。

代码实现要点
实现包含一个 Shape 基类、具体形状实现,以及一个 ShapeFactory,由类型字符串选择创建。动态扩展不改变客户端是核心思想。
为了提升鲁棒性,还应在工厂中进行空指针保护,并优先使用智能指针进行对象生命周期管理,避免手动内存管理带来的风险。
// Simple shapes with a factory
#include
#include
#include class Shape {
public:virtual void draw() const = 0;virtual ~Shape() {}
};class Circle : public Shape {
public:void draw() const override { std::cout << "Circle" << std::endl; }
};class Square : public Shape {
public:void draw() const override { std::cout << "Square" << std::endl; }
};class ShapeFactory {
public:static std::unique_ptr createShape(const std::string& type) {if (type == "circle") return std::make_unique();if (type == "square") return std::make_unique();return nullptr;}
};int main() {auto s1 = ShapeFactory::createShape("circle");if (s1) s1->draw();auto s2 = ShapeFactory::createShape("square");if (s2) s2->draw();return 0;
}


