目录
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方式。工厂模式主要用于解决对象的创建问题,通过将对象的创建过程封装在一个工厂类中,使得客户端代码不需要关心对象的具体创建细节,只需要通过工厂类来获取所需的对象实例。
工厂模式的类型
工厂模式通常分为三种类型:
-
简单工厂模式(Simple Factory Pattern):
- 简单工厂模式并不是一种严格意义上的设计模式,它更像是一种编程习惯。
- 简单工厂模式将对象的创建过程集中在一个工厂类中,客户端只需要调用工厂类的方法并传递相应的参数,工厂类就会根据参数返回相应的对象实例。
- 优点是客户端代码简洁,但缺点是工厂类集中了所有的对象创建逻辑,随着业务逻辑的复杂化,工厂类可能会变得越来越臃肿。
-
工厂方法模式(Factory Method Pattern):
- 工厂方法模式是简单工厂模式的进一步抽象和推广。
- 在工厂方法模式中,每个具体的类都有一个对应的工厂类,工厂类中定义了一个工厂方法,用于创建对应类的实例。
- 这样做的好处是将对象的创建逻辑分散到各个工厂类中,避免了工厂类的臃肿,同时也符合开闭原则(对扩展开放,对修改关闭)。
-
抽象工厂模式(Abstract Factory Pattern):
- 抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 抽象工厂模式适用于需要创建一组相关或依赖的对象的情况。
- 它通过定义一个抽象工厂接口,具体的工厂类实现这个接口,来创建一系列相关的产品对象。
- 抽象工厂模式能够确保创建的对象之间的一致性,并且易于扩展。
工厂模式的优点
- 解耦:客户端代码与具体类的创建代码分离,客户端代码只需要依赖工厂接口,而不需要依赖具体的类。
- 可扩展性:通过增加新的工厂类和产品类,可以很容易地扩展系统,而不需要修改现有代码。
- 封装性:对象的创建过程被封装在工厂类中,客户端不需要关心对象的创建细节。
工厂模式的缺点
- 增加了类的数量:工厂模式会增加系统中类的数量,在一定程度上增加了复杂性。
- 复杂性:对于简单的对象创建,使用工厂模式可能会显得过于复杂。
适用场景
- 当一个类不知道它所需要的对象的具体类时。
- 当一个类希望由其子类来指定它所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化时。
1. 简单工厂模式示例
#include <iostream>
#include <memory>
// 产品接口
class Product {
public:
virtual void use() = 0;
virtual ~Product() = default;
};
// 具体产品1
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "使用产品 A" << std::endl;
}
};
// 具体产品2
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "使用产品 B" << std::endl;
}
};
// 工厂类
class SimpleFactory {
public:
static std::unique_ptr<Product> createProduct(const std::string &type) {
if (type == "A") {
return std::make_unique<ConcreteProductA>();
} else if (type == "B") {
return std::make_unique<ConcreteProductB>();
}
return nullptr;
}
};
int main() {
auto productA = SimpleFactory::createProduct("A");
productA->use(); // 输出: 使用产品 A
auto productB = SimpleFactory::createProduct("B");
productB->use(); // 输出: 使用产品 B
return 0;
}
2. 工厂方法模式示例
#include <iostream>
#include <memory>
// 产品接口
class Product {
public:
virtual void use() = 0;
virtual ~Product() = default;
};
// 具体产品 A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "使用产品 A" << std::endl;
}
};
// 具体产品 B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "使用产品 B" << std::endl;
}
};
// 工厂接口
class ProductFactory {
public:
virtual std::unique_ptr<Product> createProduct() = 0;
virtual ~ProductFactory() = default;
};
// 具体工厂 A
class ConcreteFactoryA : public ProductFactory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ConcreteProductA>();
}
};
// 具体工厂 B
class ConcreteFactoryB : public ProductFactory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ConcreteProductB>();
}
};
int main() {
std::unique_ptr<ProductFactory> factoryA = std::make_unique<ConcreteFactoryA>();
auto productA = factoryA->createProduct();
productA->use(); // 输出: 使用产品 A
std::unique_ptr<ProductFactory> factoryB = std::make_unique<ConcreteFactoryB>();
auto productB = factoryB->createProduct();
productB->use(); // 输出: 使用产品 B
return 0;
}
3. 抽象工厂模式示例
#include <iostream>
#include <memory>
// 抽象产品 A
class AbstractProductA {
public:
virtual void use() = 0;
virtual ~AbstractProductA() = default;
};
// 抽象产品 B
class AbstractProductB {
public:
virtual void use() = 0;
virtual ~AbstractProductB() = default;
};
// 具体产品 A1
class ConcreteProductA1 : public AbstractProductA {
public:
void use() override {
std::cout << "使用产品 A1" << std::endl;
}
};
// 具体产品 A2
class ConcreteProductA2 : public AbstractProductA {
public:
void use() override {
std::cout << "使用产品 A2" << std::endl;
}
};
// 具体产品 B1
class ConcreteProductB1 : public AbstractProductB {
public:
void use() override {
std::cout << "使用产品 B1" << std::endl;
}
};
// 具体产品 B2
class ConcreteProductB2 : public AbstractProductB {
public:
void use() override {
std::cout << "使用产品 B2" << std::endl;
}
};
// 抽象工厂
class AbstractFactory {
public:
virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
virtual ~AbstractFactory() = default;
};
// 具体工厂 1
class ConcreteFactory1 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ConcreteProductA1>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ConcreteProductB1>();
}
};
// 具体工厂 2
class ConcreteFactory2 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ConcreteProductA2>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ConcreteProductB2>();
}
};
int main() {
// 使用工厂 1
std::unique_ptr<AbstractFactory> factory1 = std::make_unique<ConcreteFactory1>();
auto productA1 = factory1->createProductA();
productA1->use(); // 输出: 使用产品 A1
auto productB1 = factory1->createProductB();
productB1->use(); // 输出: 使用产品 B1
// 使用工厂 2
std::unique_ptr<AbstractFactory> factory2 = std::make_unique<ConcreteFactory2>();
auto productA2 = factory2->createProductA();
productA2->use(); // 输出: 使用产品 A2
auto productB2 = factory2->createProductB();
productB2->use(); // 输出: 使用产品 B2
return 0;
}
总结
-
简单工厂模式:通过一个工厂类根据参数创建不同类型的产品,客户端只需知道工厂类。
-
工厂方法模式:定义了一个工厂接口,每个具体工厂负责创建特定的产品,便于扩展新产品类型。
-
抽象工厂模式:主要用于创建一组相关的产品,通过具体工厂类实现,可以同时创建多个相关的产品,确保产品之间的兼容性。