工厂方法模式的含义
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,主要目的是用于创建对象,但在创建对象的过程中不会指定将要创建的对象的具体类。这种模式涉及到单个类,该类负责创建自己的对象,同时确保创建相同对象的方式一致。这样做的主要目的是将对象的创建与其使用解耦,从而提高系统的灵活性和可扩展性。
核心思想及解释
工厂方法模式的核心思想是定义一个用于创建对象的接口,但让实现这个接口的类来决定实例化哪一个类。工厂方法让类的实例化推迟到其子类。这意味着,工厂方法模式允许类将其实例化逻辑延迟到子类中执行,这样通过子类来指定创建哪个对象。
为什么要使用工厂方法模式
- 解耦: 工厂方法可以减少客户代码和具体类之间的依赖,通过工厂接口连接,可以在不修改客户代码的情况下引入新的具体类型。
- 增强灵活性和扩展性: 通过引入新的具体工厂类,可以轻松添加新的产品类型,而无需修改现有系统。
- 控制产品的生产: 使用工厂方法可以控制对象创建的时间和方式,也便于进行权限管理或者潜在的资源优化。
使用工厂方法模式需要注意的点
- 复杂度: 引入工厂方法会增加系统的复杂度,因为需要添加多个新类,每次增加新的产品类型时都需要增加新的具体工厂类。
- 系统的过度设计: 如果系统中的产品种类不多,且不太可能扩展,使用工厂方法模式可能会让设计过于复杂。
工程的应用场景
- 系统需要处理不同类型的对象,而客户端不应知道具体的实现细节时。
- 系统中的一组类的设计目的是表现某种共同的行为,但存在较大的差异性时。
- 在编程环境中,需要提供一个库或框架,用户或开发者只需要指定特定类型的名称就可以创建用户所需的实例。
示例代码及解释
假设我们正在开发一个图形编辑器,在这个编辑器中,用户可以创建不同类型的形状,如圆形和矩形。使用工厂方法模式,我们可以创建一个形状工厂,用于生成不同类型的形状对象。
首先,定义一个形状的接口和实现该接口的具体形状类:
#include <iostream>
// Shape interface
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
// Concrete class Circle
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle." << std::endl;
}
};
// Concrete class Rectangle
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a rectangle." << std::endl;
}
};
然后,定义一个工厂接口和实现该接口的具体工厂类:
// Factory interface
class ShapeFactory {
public:
virtual Shape* createShape() = 0;
virtual ~ShapeFactory() {}
};
// Concrete factory for creating Circles
class CircleFactory : public ShapeFactory {
public:
Shape* createShape() override {
return new Circle();
}
};
// Concrete factory for creating Rectangles
class RectangleFactory : public ShapeFactory {
public:
Shape* createShape() override {
return new Rectangle();
}
};
现在,客户端代码可以使用工厂方法来创建对象,而无需直接实例化对象:
int main() {
ShapeFactory* factory = new CircleFactory();
Shape* shape1 = factory->createShape();
shape1->draw();
delete factory;
delete shape1;
factory = new RectangleFactory();
Shape* shape2 = factory->createShape();
shape2->draw();
delete factory;
delete shape2;
return 0;
}
输出代码运行结果
Drawing a circle.
Drawing a rectangle.
这个示例展示了如何使用工厂方法模式来解耦对象的创建和使用,使得添加新的形状类型更加简单且不影响现有代码。