文章目录
- 一.什么是工厂方法设计模式?
- [二. 工厂方法模式的特点](#二. 工厂方法模式的特点)
- 三.工厂方法模式的结构
- 四.工厂方法模式的优缺点
- [五.工厂方法模式的 C++ 实现](#五.工厂方法模式的 C++ 实现)
- [六.工厂方法模式的 Java 实现](#六.工厂方法模式的 Java 实现)
- 七.代码解析
- 八.总结
类图: 工厂方法设计模式类图
一.什么是工厂方法设计模式?
工厂方法模式 (Factory Method Pattern) 是一种创建型设计模式,它定义了一个创建对象的接口,由子类决定要实例化的具体类。工厂方法模式让类的实例化延迟到子类,从而避免了直接在代码中使用 new 关键字实例化具体类。
二. 工厂方法模式的特点
- 解耦:将对象的创建与使用分离,降低耦合性。
- 可扩展性强:可以通过新增具体产品类和具体工厂类来扩展产品族,而无需修改现有代码。
- 遵循开闭原则:对扩展开放,对修改封闭。
三.工厂方法模式的结构
- Product(抽象产品类):定义产品的接口,具体产品需要实现此接口。
- ConcreteProduct(具体产品类):实现抽象产品接口,定义产品的具体实现。
- Creator(抽象工厂类):定义一个创建产品对象的抽象方法。
- ConcreteCreator(具体工厂类) :实现工厂方法,负责创建具体产品对象。
四.工厂方法模式的优缺点
- 优点:
- 减少耦合:客户端通过工厂方法与具体产品类解耦。
- 扩展性强:通过增加新的具体工厂和产品类来支持新功能。
- 符合设计原则:遵循单一职责和开闭原则。
- 缺点:
- 增加复杂性:需要为每种具体产品创建对应的工厂类,类的数量增加。
- 限制适用场景:工厂方法适合创建少量的产品,如果产品种类非常多,代码复杂度会增加。
五.工厂方法模式的 C++ 实现
cpp
#include <iostream>
#include <memory>
using namespace std;
// 抽象产品类
class Product {
public:
virtual void UseProduct() = 0; // 使用产品的接口
virtual ~Product() = default;
};
// 具体产品A
class ConcreteProductA : public Product {
public:
void UseProduct() override {
cout << "Using ConcreteProductA" << endl;
}
};
// 具体产品B
class ConcreteProductB : public Product {
public:
void UseProduct() override {
cout << "Using ConcreteProductB" << endl;
}
};
// 抽象工厂类
class Creator {
public:
virtual unique_ptr<Product> FactoryMethod() = 0; // 工厂方法
virtual ~Creator() = default;
};
// 具体工厂A
class ConcreteCreatorA : public Creator {
public:
unique_ptr<Product> FactoryMethod() override {
return make_unique<ConcreteProductA>(); // 创建具体产品A
}
};
// 具体工厂B
class ConcreteCreatorB : public Creator {
public:
unique_ptr<Product> FactoryMethod() override {
return make_unique<ConcreteProductB>(); // 创建具体产品B
}
};
// 测试代码
int main() {
unique_ptr<Creator> factoryA = make_unique<ConcreteCreatorA>();
unique_ptr<Product> productA = factoryA->FactoryMethod();
productA->UseProduct();
unique_ptr<Creator> factoryB = make_unique<ConcreteCreatorB>();
unique_ptr<Product> productB = factoryB->FactoryMethod();
productB->UseProduct();
return 0;
}
六.工厂方法模式的 Java 实现
java
// 抽象产品类
interface Product {
void useProduct(); // 使用产品的接口
}
// 具体产品A
class ConcreteProductA implements Product {
public void useProduct() {
System.out.println("Using ConcreteProductA");
}
}
// 具体产品B
class ConcreteProductB implements Product {
public void useProduct() {
System.out.println("Using ConcreteProductB");
}
}
// 抽象工厂类
abstract class Creator {
public abstract Product factoryMethod(); // 工厂方法
}
// 具体工厂A
class ConcreteCreatorA extends Creator {
public Product factoryMethod() {
return new ConcreteProductA(); // 创建具体产品A
}
}
// 具体工厂B
class ConcreteCreatorB extends Creator {
public Product factoryMethod() {
return new ConcreteProductB(); // 创建具体产品B
}
}
// 测试代码
public class FactoryMethodDemo {
public static void main(String[] args) {
Creator factoryA = new ConcreteCreatorA();
Product productA = factoryA.factoryMethod();
productA.useProduct();
Creator factoryB = new ConcreteCreatorB();
Product productB = factoryB.factoryMethod();
productB.useProduct();
}
}
七.代码解析
- 抽象产品类 :
- Product 定义了一个抽象接口 UseProduct,所有具体产品类都必须实现此接口。
- 通过多态,客户端代码无需关心具体产品类的类型,只需调用接口方法。
- 具体产品类 :
- ConcreteProductA 和 ConcreteProductB 是 Product 的派生类,分别实现了 UseProduct 接口。
- 每个具体产品类有自己的实现逻辑,例如打印不同的消息。
- 抽象工厂类 :
- Creator 定义了一个纯虚函数 FactoryMethod,用于创建产品。
- 通过将工厂方法定义为虚函数,使得子类可以重写以返回不同的具体产品实例。
- 具体工厂类 :
- ConcreteCreatorA 和 ConcreteCreatorB 是 Creator 的派生类,分别重写了 FactoryMethod。
- FactoryMethod 返回具体产品类的实例,这里使用了 C++11 的 unique_ptr 智能指针,避免了手动管理内存的复杂性。
- 客户端代码 :
- main 函数中,首先创建工厂对象(如 ConcreteCreatorA),通过工厂对象调用 FactoryMethod 方法获取产品实例。
- 调用产品的 UseProduct 方法进行操作。
- 使用 unique_ptr 确保资源自动释放,无需手动销毁。
八.总结
工厂方法模式是一种灵活的创建对象模式,适用于需要根据不同条件创建多种产品实例的场景。C++ 的实现中通过继承和多态实现工厂方法,同时使用智能指针避免了内存泄漏的问题。Java 的实现通过抽象类和具体类的组合也达到了类似效果。虽然工厂方法模式提高了代码的灵活性,但也增加了系统的复杂性,需要根据项目实际需求合理使用。
应用场景:
- 需要灵活创建对象:如日志记录器可以根据配置创建文件日志或数据库日志实例。
- 避免依赖具体类:如多种数据库连接类型,可以通过工厂方法动态生成。
- 需要控制对象创建逻辑:如只允许创建特定种类的实例。