23种设计模式:使用C++代码说明——简单工厂模式、工厂模式、抽象工厂模式
设计模式是在软件开发领域中针对常见问题提出的标准化、可复用的解决方案。本文主要讲述工厂模式。
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。工厂模式包括:简单工厂模式、工厂方法模式、抽象工厂模式。
创建型设计模式(Creational Design Patterns)是设计模式的一种分类,主要关注对象的创建机制。这些模式通过控制对象的创建过程,解决对象实例化的复杂性问题,使系统在创建对象时更加灵活和高效。
一,简单工厂模式
1,什么是简单工厂模式?
简单工厂模式是一种创建型设计模式,它通过一个工厂类根据传入参数动态创建不同类型的对象,将对象的实例化过程与使用分离。
关键组件:
抽象产品:定义产品接口
具体产品:实现具体的产品
总厂:根据入参创建不同的具体产品,并返回产品基类的指针,也可操作基类的指针完成一定的初始化操作。
2,代码示例
核心类组成:抽象产品类、具体产品类、工厂类。
#include <iostream>
#include <string>
#include <memory> // 智能指针
// 1. 抽象产品类
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() = default; // 虚析构保证正确释放资源
};
// 2. 具体产品类
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Rectangle" << std::endl;
}
};
class Triangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Triangle" << std::endl;
}
};
// 3. 工厂类
class ShapeFactory {
public:
// 使用智能指针自动管理内存
static std::unique_ptr<Shape> createShape(const std::string& type) {
if (type == "Circle") {
return std::make_unique<Circle>();
} else if (type == "Rectangle") {
return std::make_unique<Rectangle>();
} else if (type == "Triangle") {
return std::make_unique<Triangle>();
} else {
throw std::invalid_argument("Invalid shape type");
}
}
};
// 客户端代码
int main() {
try {
auto circle = ShapeFactory::createShape("Circle");
auto rect = ShapeFactory::createShape("Rectangle");
auto triangle = ShapeFactory::createShape("Triangle");
circle->draw(); // Drawing a Circle
rect->draw(); // Drawing a Rectangle
triangle->draw(); // Drawing a Triangle
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
3,模式特点
①、创建逻辑集中封装:将对象创建在工厂类的静态方法中集中管理
可以在工厂类的静态方法中集中管理对象的复杂的创建逻辑,便于创建逻辑的集中维护。避免复杂的初始化逻辑的代码重复。
std::unique_ptr<Shape> ShapeFactory::createShape(const std::string& type) {
if (type == "Circle") {
auto circle = std::make_unique<Circle>();
// 此处z可以添加初始化逻辑,有利于创建逻辑的统一管理。
return circle;
}
}
②、客户端与具体类解耦
工厂模式下,客户端代码不依赖具体的类。这在对象的初始化方式修改时,或者具体类的类名变化时,只需要修改工厂类的实现,不需要修改客户端的调用代码。
// 直接创建 - 客户端依赖具体类
std::unique_ptr<Shape> shape = std::make_unique<Circle>(); // 直接依赖Circle类
// 工厂模式 - 客户端只依赖抽象接口
std::unique_ptr<Shape> shape = ShapeFactory::createShape("Circle"); // 只依赖Shape接口
③、违反开闭原则:新增产品类型需修改工厂类(违反OCP)
二,工厂模式
1,什么是工厂模式?
工厂模式是一种创建型设计模式,它定义了抽象工厂,包含一个创建对象的接口,但由具体的工厂子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类。它解决了简单工厂模式违反开闭原则的问题。
关键组件:
抽象产品:定义产品接口
具体产品:实现具体的产品
抽象工厂:声明抽象方法,返回抽象产品
具体工厂:实现工厂的抽象方法,返回具体的产品
2,代码示例
#include <iostream>
#include <memory>
// 抽象产品
class BaseProduct
{
public:
virtual void operation() = 0;
virtual ~BaseProduct() = default;
};
// 具体产品
class ProductA: public BaseProduct
{
public:
void operation() override
{
std::cout << "ProductA::operation" << std::endl;
}
};
// 具体产品
class ProductB : public BaseProduct
{
public:
void operation() override
{
std::cout << "ProductB::operation" << std::endl;
}
};
// 抽象工厂
class BaseFactory
{
public:
virtual std::unique_ptr<BaseProduct> creatProduct() = 0;
virtual void useProduct()
{
std::unique_ptr<BaseProduct> product = creatProduct();
product->operation();
}
};
class FactoryA: public BaseFactory
{
public:
std::unique_ptr<BaseProduct> creatProduct() override
{
return std::make_unique<ProductA>();
}
};
class FactoryB : public BaseFactory
{
public:
std::unique_ptr<BaseProduct> creatProduct() override
{
return std::make_unique<ProductB>();
}
};
// 客户端调用代码
void clientUseProduct(std::shared_ptr<BaseFactory> factory)
{
factory->useProduct();
}
int main()
{
// UseProductA
std::shared_ptr<FactoryA> factoryA = std::make_shared<FactoryA>();
clientUseProduct(factoryA);
// UseProductB
std::shared_ptr<FactoryB> factoryB = std::make_shared<FactoryB>();
clientUseProduct(factoryB);
}
3,模式及特点
①优点
- 开闭原则支持:新增产品类型只需添加新创建者,无需修改已有代码
- 解耦程度更高:消除客户端与具体产品的耦合,客户端只依赖抽象接口(Dialog/Button),完全隔离具体实现。
- 单一职责原则(创建逻辑分离),每个具体创建者只负责一种产品,业务逻辑集中在抽象创建者。
- 支持依赖倒置原则
②典型的应用场景
- 跨平台开发:不同操作系统创建对应UI组件
- 插件系统:动态加载扩展模块时创建对象
- 框架设计:框架定义接口,用户实现具体类
三,抽象工厂模式
1,什么是抽象工厂模式
抽象工厂模式是创建型设计模式的高级形式,专注于创建相关对象的家族(产品族),而不需要指定它们的具体类。它提供了一种封装一组具有共同主题的独立工厂的方式。
2,示例代码
#include <iostream>
#include <memory>
#include <string>
#include <vector>
// 抽象产品:按钮
class Button {
public:
virtual void render() const = 0;
virtual void onClick() const = 0;
virtual ~Button() = default;
};
// 具体产品:Windows按钮
class WindowsButton : public Button {
public:
void render() const override {
std::cout << "渲染Windows按钮 [确定]\n";
}
void onClick() const override {
std::cout << "Windows按钮被点击 - 执行Windows操作\n";
}
};
// 具体产品:MacOS按钮
class MacOSButton : public Button {
public:
void render() const override {
std::cout << "渲染macOS按钮 ✅\n";
}
void onClick() const override {
std::cout << "macOS按钮被点击 - 执行macOS操作\n";
}
};
// 具体产品:Linux按钮
class LinuxButton : public Button {
public:
void render() const override {
std::cout << "渲染Linux按钮 [OK]\n";
}
void onClick() const override {
std::cout << "Linux按钮被点击 - 执行Linux操作\n";
}
};
// 抽象产品:复选框
class Checkbox {
public:
virtual void render() const = 0;
virtual void toggle() = 0;
virtual bool isChecked() const = 0;
virtual ~Checkbox() = default;
};
// 具体产品:Windows复选框
class WindowsCheckbox : public Checkbox {
bool checked = false;
public:
void render() const override {
std::cout << "Windows复选框 [" << (checked ? "X" : " ") << "]\n";
}
void toggle() override {
checked = !checked;
std::cout << (checked ? "选中" : "取消选中") << " Windows复选框\n";
}
bool isChecked() const override {
return checked;
}
};
// 具体产品:MacOS复选框
class MacOSCheckbox : public Checkbox {
bool checked = false;
public:
void render() const override {
std::cout << "macOS复选框 [" << (checked ? "✓" : " ") << "]\n";
}
void toggle() override {
checked = !checked;
std::cout << (checked ? "选中" : "取消选中") << " macOS复选框\n";
}
bool isChecked() const override {
return checked;
}
};
// 具体产品:Linux复选框
class LinuxCheckbox : public Checkbox {
bool checked = false;
public:
void render() const override {
std::cout << "Linux复选框 [" << (checked ? "*" : " ") << "]\n";
}
void toggle() override {
checked = !checked;
std::cout << (checked ? "选中" : "取消选中") << " Linux复选框\n";
}
bool isChecked() const override {
return checked;
}
};
// 抽象产品:文本输入框
class TextField {
public:
virtual void render() const = 0;
virtual void setText(const std::string& text) = 0;
virtual std::string getText() const = 0;
virtual ~TextField() = default;
};
// 具体产品:Windows文本输入框
class WindowsTextField : public TextField {
std::string text;
public:
void render() const override {
std::cout << "Windows文本输入框: [" << text << "]\n";
}
void setText(const std::string& text) override {
this->text = text;
std::cout << "设置Windows文本输入框内容: " << text << "\n";
}
std::string getText() const override {
return text;
}
};
// 具体产品:MacOS文本输入框
class MacOSTextField : public TextField {
std::string text;
public:
void render() const override {
std::cout << "macOS文本输入框: \"" << text << "\"\n";
}
void setText(const std::string& text) override {
this->text = text;
std::cout << "设置macOS文本输入框内容: " << text << "\n";
}
std::string getText() const override {
return text;
}
};
// 具体产品:Linux文本输入框
class LinuxTextField : public TextField {
std::string text;
public:
void render() const override {
std::cout << "Linux文本输入框: |" << text << "|\n";
}
void setText(const std::string& text) override {
this->text = text;
std::cout << "设置Linux文本输入框内容: " << text << "\n";
}
std::string getText() const override {
return text;
}
};
// 抽象工厂
class UIFactory {
public:
virtual std::unique_ptr<Button> createButton() const = 0;
virtual std::unique_ptr<Checkbox> createCheckbox() const = 0;
virtual std::unique_ptr<TextField> createTextField() const = 0;
virtual void renderHeader() const = 0;
virtual ~UIFactory() = default;
};
// 具体工厂:Windows工厂
class WindowsUIFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() const override {
return std::make_unique<WindowsButton>();
}
std::unique_ptr<Checkbox> createCheckbox() const override {
return std::make_unique<WindowsCheckbox>();
}
std::unique_ptr<TextField> createTextField() const override {
return std::make_unique<WindowsTextField>();
}
void renderHeader() const override {
std::cout << "======================\n";
std::cout << " WINDOWS 应用程序 \n";
std::cout << "======================\n";
}
};
// 具体工厂:MacOS工厂
class MacOSUIFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() const override {
return std::make_unique<MacOSButton>();
}
std::unique_ptr<Checkbox> createCheckbox() const override {
return std::make_unique<MacOSCheckbox>();
}
std::unique_ptr<TextField> createTextField() const override {
return std::make_unique<MacOSTextField>();
}
void renderHeader() const override {
std::cout << "••••••••••••••••••••••\n";
std::cout << " macOS 应用程序 \n";
std::cout << "••••••••••••••••••••••\n";
}
};
// 具体工厂:Linux工厂
class LinuxUIFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() const override {
return std::make_unique<LinuxButton>();
}
std::unique_ptr<Checkbox> createCheckbox() const override {
return std::make_unique<LinuxCheckbox>();
}
std::unique_ptr<TextField> createTextField() const override {
return std::make_unique<LinuxTextField>();
}
void renderHeader() const override {
std::cout << "------------------------\n";
std::cout << " Linux 应用程序 \n";
std::cout << "------------------------\n";
}
};
// 客户端代码 - 应用程序
class Application {
std::unique_ptr<UIFactory> factory;
std::vector<std::unique_ptr<Button>> buttons;
std::vector<std::unique_ptr<Checkbox>> checkboxes;
std::vector<std::unique_ptr<TextField>> textFields;
public:
Application(std::unique_ptr<UIFactory> factory)
: factory(std::move(factory)) {}
void createUI() {
// 创建UI组件
buttons.push_back(this->factory->createButton());
buttons.push_back(this->factory->createButton());
checkboxes.push_back(this->factory->createCheckbox());
textFields.push_back(this->factory->createTextField());
}
void renderUI() const {
factory->renderHeader();
std::cout << "\n渲染按钮:\n";
for (const auto& btn : buttons) {
btn->render();
}
std::cout << "\n渲染复选框:\n";
for (const auto& cb : checkboxes) {
cb->render();
}
std::cout << "\n渲染文本输入框:\n";
for (const auto& tf : textFields) {
tf->render();
}
}
void simulateUserInteraction() {
std::cout << "\n=== 用户交互模拟 ===\n";
// 与第一个按钮交互
std::cout << "\n点击第一个按钮:\n";
buttons[0]->onClick();
// 切换复选框状态
std::cout << "\n切换复选框状态:\n";
checkboxes[0]->toggle();
// 在文本框中输入内容
std::cout << "\n在文本框中输入内容:\n";
textFields[0]->setText("设计模式示例");
// 重新渲染UI
std::cout << "\n更新后的UI状态:\n";
renderUI();
}
};
// 工厂选择器
std::unique_ptr<UIFactory> createUIFactory(const std::string& osType) {
if (osType == "Windows") {
return std::make_unique<WindowsUIFactory>();
} else if (osType == "MacOS") {
return std::make_unique<MacOSUIFactory>();
} else if (osType == "Linux") {
return std::make_unique<LinuxUIFactory>();
}
throw std::runtime_error("不支持的OS类型");
}
int main() {
try {
// 创建Windows应用
std::cout << "创建Windows应用:\n";
auto winApp = Application(createUIFactory("Windows"));
winApp.createUI();
winApp.renderUI();
winApp.simulateUserInteraction();
// 创建Mac应用
std::cout << "\n\n创建macOS应用:\n";
auto macApp = Application(createUIFactory("MacOS"));
macApp.createUI();
macApp.renderUI();
macApp.simulateUserInteraction();
// 创建Linux应用
std::cout << "\n\n创建Linux应用:\n";
auto linuxApp = Application(createUIFactory("Linux"));
linuxApp.createUI();
linuxApp.renderUI();
linuxApp.simulateUserInteraction();
} catch (const std::exception& e) {
std::cerr << "错误: " << e.what() << std::endl;
}
return 0;
}
3,优势
①产品族一致性:
确保创建的所有对象属于同一家族。例如:所有Windows组件或所有MacOS组件
②解耦客户端代码:
- 客户端只与抽象接口交互
- 不依赖具体实现类
③开闭原则支持:
- 添加新产品族容易
- 新增具体工厂不影响现有代码
④单一职责原则:
每个具体工厂只负责创建特定产品族
⑤可扩展性:
⑥易于添加新的产品族(如AndroidUI)
4,模式局限性
①添加新产品困难:
- 新增产品类型需要修改所有工厂接口
- 违反开闭原则
②复杂性增加:
- 需要创建大量类
- 可能过度设计简单场景
更多推荐
所有评论(0)