一、 什么是工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但是将对象的实例化过程推迟到子类中。工厂模式允许通过调用一个共同的接口方法来创建不同类型的对象,而无需暴露对象的实例化逻辑。
工厂模式的主要目标是解耦对象的创建和使用,以及提供一种更灵活的方式来管理对象的实例化。通过使用工厂模式,可以轻松添加新类型的对象,而不会影响到已有的代码。
工厂模式通常涉及以下几个核心角色:
- 产品(Product):这是一个抽象类或接口,定义了所创建对象的通用接口。
- 具体产品(Concrete Product):这些是实现了产品接口的具体类,它们是工厂方法模式的创建目标。
- 工厂(Factory):这是一个抽象类或接口,定义了创建对象的接口方法。工厂类通常是一个创建具体产品对象的工厂方法。
- 具体工厂(Concrete Factory):这些是实现了工厂接口的具体类,它们负责实例化具体的产品对象。
工厂模式可以分为三种常见的变体:
- 简单工厂模式(Simple Factory Pattern):通过一个共同的工厂类来创建对象,客户端只需传递一个参数来指定所需的对象类型。虽然不是严格意义上的设计模式,但它是工厂模式的基础。
- 工厂方法模式(Factory Method Pattern):定义一个工厂接口,具体的工厂子类负责实现工厂接口并创建对象。每个具体工厂对应一个特定的产品。
- 抽象工厂模式(Abstract Factory Pattern):提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体类。适用于创建一组相互关联的产品。
二、简单工厂模式的代码样例
简单工厂模式(Simple Factory Pattern)虽然不是严格的设计模式,但它是工厂模式的一种基本形式,适用于创建单一类别的对象。在简单工厂模式中,有一个工厂类负责根据客户端的请求创建不同类型的对象。
以下是一个用C++实现简单工厂模式的示例:
#include <iostream>
// 抽象产品类
class Product {
public:
virtual void operation() = 0;
};
// 具体产品类A
class ConcreteProductA : public Product {
public:
void operation() override {
std::cout << "ConcreteProductA operation." << std::endl;
}
};
// 具体产品类B
class ConcreteProductB : public Product {
public:
void operation() override {
std::cout << "ConcreteProductB operation." << std::endl;
}
};
// 简单工厂类
class SimpleFactory {
public:
// 根据传入的参数创建不同类型的产品对象
static Product* createProduct(char type) {
if (type == 'A') {
return new ConcreteProductA();
} else if (type == 'B') {
return new ConcreteProductB();
} else {
return nullptr; // 可以抛出异常或其他处理
}
}
};
int main() {
// 客户端通过工厂创建产品
Product* productA = SimpleFactory::createProduct('A');
Product* productB = SimpleFactory::createProduct('B');
if (productA) {
productA->operation();
delete productA;
}
if (productB) {
productB->operation();
delete productB;
}
return 0;
}
在这个例子中,我们定义了一个抽象产品类 Product,然后有两个具体的产品类 ConcreteProductA 和 ConcreteProductB。简单工厂类 SimpleFactory 有一个静态方法 createProduct,根据传入的参数来创建不同类型的产品对象。
虽然简单工厂模式简化了对象的实例化,但它的弊端在于如果需要添加新类型的产品,就需要修改工厂类的代码。因此,当需要支持更多产品类型时,更推荐使用工厂方法模式或抽象工厂模式。
三、工厂方法模式的代码样例
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但是将具体的对象实例化推迟到子类中。每个具体的工厂子类负责创建特定类型的对象。这种模式使得客户端代码与具体创建对象的代码分离,实现了松耦合。
以下是一个用C++实现工厂方法模式的示例:
#include <iostream>
// 抽象产品类
class Product {
public:
virtual void operation() = 0;
};
// 具体产品类A
class ConcreteProductA : public Product {
public:
void operation() override {
std::cout << "ConcreteProductA operation." << std::endl;
}
};
// 具体产品类B
class ConcreteProductB : public Product {
public:
void operation() override {
std::cout << "ConcreteProductB operation." << std::endl;
}
};
// 抽象工厂类
class Factory {
public:
virtual Product* createProduct() = 0;
};
// 具体工厂类A
class ConcreteFactoryA : public Factory {
public:
Product* createProduct() override {
return new ConcreteProductA();
}
};
// 具体工厂类B
class ConcreteFactoryB : public Factory {
public:
Product* createProduct() override {
return new ConcreteProductB();
}
};
int main() {
// 客户端通过具体工厂来创建产品
Factory* factoryA = new ConcreteFactoryA();
Product* productA = factoryA->createProduct();
productA->operation();
delete factoryA;
delete productA;
Factory* factoryB = new ConcreteFactoryB();
Product* productB = factoryB->createProduct();
productB->operation();
delete factoryB;
delete productB;
return 0;
}
在这个例子中,我们定义了一个抽象产品类 Product,然后有两个具体的产品类 ConcreteProductA 和 ConcreteProductB。抽象工厂类 Factory 定义了一个纯虚函数 createProduct,由具体的工厂子类来实现该方法并创建特定类型的产品对象。
客户端使用具体的工厂类来创建产品,这样客户端代码与具体的产品创建代码分离,实现了解耦。工厂方法模式允许通过添加新的工厂子类来支持新的产品类型,而无需修改现有的代码。
四、抽象工厂模式的代码样例
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口用于创建一系列相关或相互依赖的对象,而无需指定具体类。抽象工厂模式适用于需要创建一组相互关联的产品的情况,它将一组相关的工厂类封装起来。
以下是一个用C++实现抽象工厂模式的示例:
#include <iostream>
// 抽象产品类A
class AbstractProductA {
public:
virtual void operationA() = 0;
};
// 具体产品类A1
class ConcreteProductA1 : public AbstractProductA {
public:
void operationA() override {
std::cout << "ConcreteProductA1 operation." << std::endl;
}
};
// 具体产品类A2
class ConcreteProductA2 : public AbstractProductA {
public:
void operationA() override {
std::cout << "ConcreteProductA2 operation." << std::endl;
}
};
// 抽象产品类B
class AbstractProductB {
public:
virtual void operationB() = 0;
};
// 具体产品类B1
class ConcreteProductB1 : public AbstractProductB {
public:
void operationB() override {
std::cout << "ConcreteProductB1 operation." << std::endl;
}
};
// 具体产品类B2
class ConcreteProductB2 : public AbstractProductB {
public:
void operationB() override {
std::cout << "ConcreteProductB2 operation." << std::endl;
}
};
// 抽象工厂类
class AbstractFactory {
public:
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
};
// 具体工厂类1
class ConcreteFactory1 : public AbstractFactory {
public:
AbstractProductA* createProductA() override {
return new ConcreteProductA1();
}
AbstractProductB* createProductB() override {
return new ConcreteProductB1();
}
};
// 具体工厂类2
class ConcreteFactory2 : public AbstractFactory {
public:
AbstractProductA* createProductA() override {
return new ConcreteProductA2();
}
AbstractProductB* createProductB() override {
return new ConcreteProductB2();
}
};
int main() {
// 客户端通过具体工厂来创建一组相关的产品
AbstractFactory* factory1 = new ConcreteFactory1();
AbstractProductA* productA1 = factory1->createProductA();
AbstractProductB* productB1 = factory1->createProductB();
productA1->operationA();
productB1->operationB();
delete factory1;
delete productA1;
delete productB1;
AbstractFactory* factory2 = new ConcreteFactory2();
AbstractProductA* productA2 = factory2->createProductA();
AbstractProductB* productB2 = factory2->createProductB();
productA2->operationA();
productB2->operationB();
delete factory2;
delete productA2;
delete productB2;
return 0;
}
在这个例子中,我们定义了两组相关的产品类:AbstractProductA 和 AbstractProductB,然后分别有两个具体的产品类。抽象工厂类 AbstractFactory 定义了两个纯虚函数,分别用于创建 AbstractProductA 和 AbstractProductB 对象。具体的工厂类 ConcreteFactory1 和 ConcreteFactory2 实现了这些方法,并创建特定类型的产品对象。
通过使用抽象工厂模式,客户端可以通过具体的工厂来创建一组相关的产品,实现了一种创建一系列相互关联产品的方式。这有助于实现高内聚、低耦合的设计。
五、三种工厂模式之间的关系
这三种工厂模式(简单工厂模式、工厂方法模式和抽象工厂模式)都是创建型设计模式,旨在解决对象的创建问题。它们之间有一些共同点,但也存在一些差异。下面是它们之间的关系和区别:
共同点:
- 都关注对象的创建,封装了对象的实例化过程,使客户端代码与具体创建逻辑分离。
- 都遵循了开闭原则,即可以通过添加新的产品类或工厂类来扩展功能,而无需修改现有代码。
差异:
- 简单工厂模式:虽然不是严格意义上的设计模式,但它是工厂模式的基础。它通过一个共同的工厂类来创建不同类型的对象,客户端根据参数来指定对象类型。适用于创建单一类别的对象。
- 工厂方法模式:定义了一个工厂接口,由具体的工厂子类来实现工厂接口并创建特定类型的产品对象。每个工厂只负责创建一种产品。适用于创建一组相关的产品,每个产品有一个对应的工厂。
- 抽象工厂模式:提供了一种创建一组相关或相互依赖对象的接口,每个具体的工厂子类负责创建一组相关产品。适用于创建一组相互关联的产品,每组产品都有一个对应的工厂。
适用场景:
- 简单工厂模式适用于创建简单的对象,例如基于传入参数创建对象的情况。
- 工厂方法模式适用于需要创建多种具有相同接口的产品,而且每种产品都有对应的工厂。
- 抽象工厂模式适用于创建一组相关或相互依赖的产品,且每组产品都有对应的工厂。
总之,这三种工厂模式都在不同情况下提供了灵活的对象创建机制,可以根据具体的需求来选择合适的模式。简单工厂模式通常是基础,而工厂方法模式和抽象工厂模式则在更复杂的场景下提供更大的灵活性。