文章目录
- 定义
- 示例
- 实际应用
定义
工厂方法模式,定义一个用于创建对象的接口(工厂方法),返回对象基类,让子类去实现该接口,从而返回具体的子类对象。
结构
工厂方法模式包含以下主要角色:
- 抽象产品(Product):定义产品的接口,是工厂方法模式创建的对象的超类型。
- 具体产品(Concrete Product):实现抽象产品接口的具体类。
- 抽象工厂(Creator):声明创建产品对象的工厂方法,是工厂方法模式的核心。
- 具体工厂(Concrete Creator):实现抽象工厂接口,返回具体产品的实例。
工作原理
- 客户端通过调用抽象工厂中的工厂方法来创建产品对象,而不需要关心具体产品是如何创建的。
- 具体工厂实现了抽象工厂中的工厂方法,根据客户端的需求创建具体产品对象。
- 具体产品是抽象产品的具体实现,它们实现了抽象产品定义的接口。
示例
以下是一个简单的 C++ 示例:
#include <iostream>
// 抽象产品类
class Product {
public:
virtual ~Product() {}
public:
virtual void Operation() const = 0;
};
// 具体产品类 A
class ConcreteProductA : public Product {
public:
void Operation() const override {
std::cout << "ConcreteProductA operation." << std::endl;
}
};
// 具体产品类 B
class ConcreteProductB : public Product {
public:
void Operation() const override {
std::cout << "ConcreteProductB operation." << std::endl;
}
};
// 抽象工厂类
class Creator {
public:
virtual ~Creator() {}
public:
virtual Product* factoryMethod() const = 0;
};
// 具体工厂类 A
class ConcreteCreatorA : public Creator {
public:
Product* factoryMethod() const override {
return new ConcreteProductA();
}
};
// 具体工厂类 B
class ConcreteCreatorB : public Creator {
public:
Product* factoryMethod() const override {
return new ConcreteProductB();
}
};
int main() {
// 使用具体工厂 A 创建具体产品 A
Creator* creatorA = new ConcreteCreatorA();
Product* productA = creatorA->factoryMethod();
productA->operation();
delete creatorA;
delete productA;
// 使用具体工厂 B 创建具体产品 B
Creator* creatorB = new ConcreteCreatorB();
Product* productB = creatorB->factoryMethod();
productB->operation();
delete creatorB;
delete productB;
return 0;
}
在这个示例中,Product 是抽象产品类,定义了产品的操作接口。ConcreteProductA 和 ConcreteProductB 是具体产品类,分别实现了抽象产品类的接口。Creator 是抽象工厂类,定义了工厂方法 factoryMethod(),负责创建产品对象。ConcreteCreatorA 和 ConcreteCreatorB 是具体工厂类,分别实现了工厂方法,用于创建具体产品 A 和 B。客户端通过具体工厂类来创建具体产品对象,而不需要直接与具体产品类交互。
实际应用
该模式的缺点显而易见,我们需要为每一类Product定义一个Creator类,同时需要为每个具体的Product实现具体的Creator类,十分繁琐。
当然,我们可以通过参数化工厂方法来解决这一问题,这又绕回到了简单工厂模式:
// 工厂类
class SimpleFactory {
public:
static Product* createProduct(char type) {
if (type == 'A') {
return new ConcreteProductA();
} else if (type == 'B') {
return new ConcreteProductB();
}
return nullptr;
}
};
createProduct方法通过传递不同的参数来实例化不同的子类。
我们可以借助模板,来避免反复编写重复的Creator类:
class Creator {
public:
virutal ~Creator() = default;
public:
virtual Product* CreateProduct() = 0;
};
template<typename Product>
class StandardCreator : public Creator {
public:
virtual Product* CreateProduct() {
return new Product;
}
};
当然,还是有一定的缺陷,只能使用无参构造,或者说只能使用一种类型的构造。
实际工程里,我经常把工厂方法内嵌到产品类中,这样不用工厂类。
class Product {
public:
~Product() = default;
};
class ConcreateProduct {
public:
~Product() = default;
public:
static ConcreateProduct* CreateConcreateProduct() {
return new ConcreateProduct;
}
};
工厂方法是static的,因此可以脱离对象调用。