如何实现工厂模式?
概念
工厂模式(Factory Pattern)是一种创建对象的设计模式,提供了一个接口用于创建对象,但由子类决定要实例化的类是哪一个。这种模式可以解耦对象的创建与使用,使得代码更加灵活和易于扩展。
简单工厂模式
简单工厂模式定义了一个工厂类,根据输入的参数返回不同类型的对象。虽然这不是一个正式的设计模式,但它是工厂模式的基础。
#include <iostream>
#include <memory>
#include <string>
// 产品基类
class Product {
public:
virtual void use() = 0; // 纯虚函数
virtual ~Product() = default; // 虚析构函数
};
// 具体产品 A
class ProductA : public Product {
public:
void use() override {
std::cout << "Using Product A" << std::endl;
}
};
// 具体产品 B
class ProductB : public Product {
public:
void use() override {
std::cout << "Using Product B" << std::endl;
}
};
// 简单工厂
class SimpleFactory {
public:
// 工厂方法,根据类型创建不同产品
static std::unique_ptr<Product> createProduct(const std::string& type) {
if (type == "A") {
return std::make_unique<ProductA>();
} else if (type == "B") {
return std::make_unique<ProductB>();
}
return nullptr; // 返回空指针
}
};
int main() {
// 使用工厂创建不同类型的产品
std::unique_ptr<Product> productA = SimpleFactory::createProduct("A");
if (productA) {
productA->use();
}
std::unique_ptr<Product> productB = SimpleFactory::createProduct("B");
if (productB) {
productB->use();
}
return 0;
}
代码解析
- 产品基类 (Product):定义了一个接口,所有具体产品都需要实现这个接口。
- 具体产品 (ProductA, ProductB):实现了基类的接口。
- 简单工厂 (SimpleFactory):根据输入字符串类型返回相应的产品实例。
- 客户端代码:通过简单工厂创建所需产品并使用。
工厂方法模式
工厂方法模式定义了一个接口来创建对象,但让子类决定实例化哪一个类。这样可以将对象的创建逻辑推向子类,保持高内聚、低耦合。
#include <iostream>
#include <memory>
// 产品基类
class Product {
public:
virtual void use() = 0;
virtual ~Product() = default;
};
// 具体产品 A
class ProductA : public Product {
public:
void use() override {
std::cout << "Using Product A" << std::endl;
}
};
// 具体产品 B
class ProductB : public Product {
public:
void use() override {
std::cout << "Using Product B" << std::endl;
}
};
// 工厂基类
class Factory {
public:
virtual std::unique_ptr<Product> createProduct() = 0; // 工厂方法
virtual ~Factory() = default;
};
// 具体工厂 A
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductA>(); // 创建产品 A
}
};
// 具体工厂 B
class FactoryB : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductB>(); // 创建产品 B
}
};
int main() {
std::unique_ptr<Factory> factoryA = std::make_unique<FactoryA>();
std::unique_ptr<Product> productA = factoryA->createProduct();
productA->use();
std::unique_ptr<Factory> factoryB = std::make_unique<FactoryB>();
std::unique_ptr<Product> productB = factoryB->createProduct();
productB->use();
return 0;
}
代码解析
- 工厂基类 (Factory):定义工厂方法接口。
- 具体工厂 (FactoryA, FactoryB):实现工厂方法,返回不同的产品。
- 客户端代码:通过具体工厂创建对应的产品并使用。
抽象工厂模式
抽象工厂模式提供一个接口用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。这通常用于需要产品系列中的多个产品的情况。
#include <iostream>
#include <memory>
// 产品接口
class Button {
public:
virtual void paint() = 0;
virtual ~Button() = default;
};
// 具体产品 A
class WinButton : public Button {
public:
void paint() override {
std::cout << "Rendering a Windows Button." << std::endl;
}
};
// 具体产品 B
class MacButton : public Button {
public:
void paint() override {
std::cout << "Rendering a Mac Button." << std::endl;
}
};
// 产品接口
class Checkbox {
public:
virtual void paint() = 0;
virtual ~Checkbox() = default;
};
// 具体产品 A
class WinCheckbox : public Checkbox {
public:
void paint() override {
std::cout << "Rendering a Windows Checkbox." << std::endl;
}
};
// 具体产品 B
class MacCheckbox : public Checkbox {
public:
void paint() override {
std::cout << "Rendering a Mac Checkbox." << std::endl;
}
};
// 抽象工厂
class GUIFactory {
public:
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<Checkbox> createCheckbox() = 0;
virtual ~GUIFactory() = default;
};
// 具体工厂 A
class WinFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<WinButton>();
}
std::unique_ptr<Checkbox> createCheckbox() override {
return std::make_unique<WinCheckbox>();
}
};
// 具体工厂 B
class MacFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<MacButton>();
}
std::unique_ptr<Checkbox> createCheckbox() override {
return std::make_unique<MacCheckbox>();
}
};
// 客户端代码
void renderUI(GUIFactory& factory) {
auto button = factory.createButton();
button->paint();
auto checkbox = factory.createCheckbox();
checkbox->paint();
}
int main() {
WinFactory factory;
renderUI(factory);
MacFactory macFactory;
renderUI(macFactory);
return 0;
}
代码解析
- 产品接口 (Button, Checkbox):定义不同类型的产品接口。
- 具体产品 (WinButton, MacButton, WinCheckbox, MacCheckbox):实现不同平台的具体产品。
- 抽象工厂 (GUIFactory):定义创建产品方法的接口。
- 具体工厂 (WinFactory, MacFactory):实现产品创建方法,返回平台特定的产品。
- 客户端代码:可以轻松切换工厂,实现不同平台的界面。
总结
工厂模式通过提供一个接口来创建对象,将对象的创建过程与使用解耦。简单工厂适合小型应用,工厂方法模式适合需要扩展性和可维护性的应用,而抽象工厂模式适合复杂的产品系列。根据具体需求选择合适的工厂模式可以提高代码的灵活性和可维护性。