工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,而无需暴露对象创建的逻辑细节。工厂模式通过使用工厂类来创建对象,将对象的创建和使用解耦,使得系统更加灵活、可扩展和易于维护。
工厂模式主要分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。每种模式都有不同的应用场景和实现方式。
1. 简单工厂模式
简单工厂模式通过一个工厂类来负责创建不同类型的对象,客户端只需要知道工厂类的接口,而无需关心具体对象的创建过程。这种模式适用于需要创建的对象类型较少且不会频繁变化的场景。
优点:
- 将对象的创建和使用分离,客户端只需与工厂类交互,降低了耦合度。
- 简化了客户端代码,使得客户端无需知道具体产品的创建细节。
缺点:
- 添加新产品类型需要修改工厂类,违反了开放-封闭原则。
- 工厂类可能会变得庞大,包含过多的创建逻辑。
首先,定义一个抽象产品类 Product
和两个具体产品类 ConcreteProductA
和 ConcreteProductB
:
#include <iostream>
// Abstract Product
class Product {
public:
virtual void use() const = 0;
};
// Concrete Product A
class ConcreteProductA : public Product {
public:
void use() const override {
std::cout << "Using Concrete Product A" << std::endl;
}
};
// Concrete Product B
class ConcreteProductB : public Product {
public:
void use() const override {
std::cout << "Using Concrete Product B" << std::endl;
}
};
接下来,定义工厂类 SimpleFactory
,它包含一个静态方法 createProduct
来创建不同类型的产品:
// Simple Factory
class SimpleFactory {
public:
enum ProductType { TypeA, TypeB };
static Product* createProduct(ProductType type) {
switch (type) {
case TypeA:
return new ConcreteProductA();
case TypeB:
return new ConcreteProductB();
default:
return nullptr;
}
}
};
最后,在主函数中使用简单工厂模式创建产品并调用其方法:
int main() {
// Create Concrete Product A
Product* productA = SimpleFactory::createProduct(SimpleFactory::TypeA);
if (productA) {
productA->use();
delete productA;
}
// Create Concrete Product B
Product* productB = SimpleFactory::createProduct(SimpleFactory::TypeB);
if (productB) {
productB->use();
delete productB;
}
return 0;
}
2. 工厂方法模式
工厂方法模式定义了一个创建对象的接口,但将具体对象的创建延迟到子类中实现。每个子类都可以根据需求来创建自己特定的对象,从而提供了一种扩展的方式。
优点:
- 具体产品的创建延迟到子类中实现,符合开放-封闭原则。
- 每个子类可以根据需要创建特定的产品,灵活性高。
缺点:
- 每增加一个产品,都需要增加一个对应的工厂类,导致类的数量增加。
// 抽象产品
class Vehicle {
public:
virtual void move() = 0;
};
// 具体产品
class Car : public Vehicle {
public:
void move() override {
cout << "Car is moving." << endl;
}
};
class Bike : public Vehicle {
public:
void move() override {
cout << "Bike is moving." << endl;
}
};
// 抽象工厂
class TransportFactory {
public:
virtual Vehicle* createTransport() = 0;
};
// 具体工厂
class CarFactory : public TransportFactory {
public:
Vehicle* createTransport() override {
return new Car();
}
};
class BikeFactory : public TransportFactory {
public:
Vehicle* createTransport() override {
return new Bike();
}
};
int main() {
TransportFactory* carFactory = new CarFactory();
Vehicle* car = carFactory->createTransport();
car->move();
TransportFactory* bikeFactory = new BikeFactory();
Vehicle* bike = bikeFactory->createTransport();
bike->move();
delete car;
delete bike;
delete carFactory;
delete bikeFactory;
return 0;
}
3. 抽象工厂模式
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体的类。它是工厂方法模式的扩展,用于创建一组相关的产品对象。
优点:
- 提供了一种创建一组相关或依赖对象的方式,保证这些对象能够协同工作。
- 客户端与具体工厂类分离,更容易替换具体工厂类以及产品系列。
缺点:
- 扩展新的产品族比较困难,需要修改抽象工厂接口以及所有具体工厂的实现。
#include <iostream>
#include <string>
// 抽象产品类 - 椅子
class Chair {
public:
virtual std::string getType() = 0;
};
// 具体产品类 - 现代椅子
class ModernChair : public Chair {
public:
std::string getType() override {
return "Modern Chair";
}
};
// 具体产品类 - 维多利亚椅子
class VictorianChair : public Chair {
public:
std::string getType() override {
return "Victorian Chair";
}
};
// 抽象产品类 - 沙发
class Sofa {
public:
virtual std::string getType() = 0;
};
// 具体产品类 - 现代沙发
class ModernSofa : public Sofa {
public:
std::string getType() override {
return "Modern Sofa";
}
};
// 具体产品类 - 维多利亚沙发
class VictorianSofa : public Sofa {
public:
std::string getType() override {
return "Victorian Sofa";
}
};
// 抽象工厂类
class FurnitureFactory {
public:
virtual Chair* createChair() = 0;
virtual Sofa* createSofa() = 0;
};
// 具体工厂类 - 现代家具工厂
class ModernFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new ModernChair();
}
Sofa* createSofa() override {
return new ModernSofa();
}
};
// 具体工厂类 - 维多利亚家具工厂
class VictorianFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new VictorianChair();
}
Sofa* createSofa() override {
return new VictorianSofa();
}
};
int main() {
// 现代家具工厂
FurnitureFactory* modernFactory = new ModernFurnitureFactory();
Chair* modernChair = modernFactory->createChair();
Sofa* modernSofa = modernFactory->createSofa();
std::cout << "Modern Furniture: " << modernChair->getType() << ", " << modernSofa->getType() << std::endl;
// 维多利亚家具工厂
FurnitureFactory* victorianFactory = new VictorianFurnitureFactory();
Chair* victorianChair = victorianFactory->createChair();
Sofa* victorianSofa = victorianFactory->createSofa();
std::cout << "Victorian Furniture: " << victorianChair->getType() << ", " << victorianSofa->getType() << std::endl;
// 清理
delete modernFactory;
delete modernChair;
delete modernSofa;
delete victorianFactory;
delete victorianChair;
delete victorianSofa;
return 0;
}
特点:
简单工厂 Simple Factory:
把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象。
客户不用自己负责new对象,不用了解对象创建的详细过程
提供创建对象实例的接口函数不闭合,不能对修改关闭
工厂方法 Factory Method
Factory基类,提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负
责创建对应的产品,可以做到不同产品,在不同工厂里面创建,能够对现有工厂,
以及产品的修改关闭
实际上,很多产品是有关联关系的,属于一个产品簇,不应该放在不同的工厂里面区创建,这样
1、不符合实际的产品对象创建逻辑。2、工厂类太多,不好维护
抽象工厂 Abstract Factory
把有关联关系的,属于一个产品簇的所有产品创建的接口函数,放在一个抽象工厂里面
AbstractFactory,派生类(具体产品的工厂)应该负责该产品簇里面所有的产品
总结:
在实际应用中,选择合适的工厂模式取决于需求的复杂性和扩展性。简单工厂模式适用于产品类型较少且不频繁变化的情况;工厂方法模式适用于产品类型多且需要灵活扩展的情况;抽象工厂模式适用于需要创建一组相关产品族并保证其协同工作的情况。