设计模式-工厂模式
- 软件开发
- 2025-09-02 23:36:01

设计模式 - 工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,从而使得一个类的实例化延迟到子类。工厂模式通过将对象创建的逻辑抽象化,减少了客户端代码与具体类之间的耦合。
工厂模式通常通过工厂类来实现,工厂类负责根据需求创建不同的对象。工厂模式常见的有以下几种变种:
简单工厂模式(Simple Factory Pattern)工厂方法模式(Factory Method Pattern)抽象工厂模式(Abstract Factory Pattern) 1. 简单工厂模式 定义:简单工厂模式定义了一个工厂类,它根据不同的输入条件创建不同的产品类实例。客户端通过工厂类来获取所需的对象,而不需要关心对象是如何创建的。 示例:
假设我们有两种产品:ProductA 和 ProductB。客户端通过简单工厂来选择要创建的产品。
结构框图
代码实现
#include <iostream> // 产品基类 class Product { public: // 纯虚函数 -> 实现多态(统一抽象化接口) virtual void showProduct() = 0; virtual ~Product() = default; }; // 具体产品A class ConcreteProductA : public Product { public: // 重写基类虚函数 void showProduct() override { std::cout << "Create Product A" << std::endl; } }; // 具体产品B class ConcreteProductB : public Product { public: // 重写基类虚函数 void showProduct() override { std::cout << "Create Product B" << std::endl; } }; // 简单工厂类, 用于去创建产品 class SimpleFactory { public: Product* createProduct(char type) { if (type == 'A') { return new ConcreteProductA(); } else if (type == 'B') { return new ConcreteProductB(); } else { return nullptr; } } }; int main() { // 通过简单工厂创建产品 SimpleFactory myfactory; // 利用简单工厂创建产品A Product* productA = myfactory.createProduct('A'); if(productA) { productA->showProduct(); } // 利用简单工厂创建产品B Product* productB = myfactory.createProduct('B'); if(productB) { productB->showProduct(); } delete productA; delete productB; return 1; }说明:
优点:客户端不需要知道具体类的实现,代码解耦。缺点:随着产品种类的增加,工厂类变得越来越庞大,不符合开闭原则(对修改关闭,对扩展开放)。 2. 工厂方法模式(Factory Method Pattern) 定义: 封闭-开放 原则:新添加的功能不用去修改以前已经创建的类的内容工厂方法模式将对象的创建推迟到子类,允许子类决定要创建的对象类型。通过定义一个抽象工厂接口,每个具体工厂只负责创建**一个**特定类型的对象。 示例:
添加一个新的产品,只用新建其对应的产品类以及对于产品工厂类 将简单工厂模式中的产品创建移交给具体工厂类来实现。结构框图
代码实现
#include <iostream> class Product { public: virtual void showProduct() = 0; // virtual ~Product() = default; }; class ConcreteProductA : public Product { public: void showProduct() override { std::cout << "A product show (method factory)\n"; } }; class ConcreteProductB : public Product { public: void showProduct() override { std::cout << "B product show (method factory)\n"; } }; // 工厂接口 class Factory { public: virtual Product* createProduct(void) = 0; virtual ~Factory() = default; }; // 具体工厂A接口 class ConcreteFactoryA : public Factory { Product* createProduct(void) override { return new ConcreteProductA; } }; // 具体工厂B接口 class ConcreteFactoryB : public Factory { Product* createProduct(void) override { return new ConcreteProductB; } }; int main() { Factory* factoryA = new ConcreteFactoryA; Factory* factoryB = new ConcreteFactoryB; Product* productA = factoryA->createProduct(); Product* productB = factoryB->createProduct(); productA->showProduct(); productB->showProduct(); delete factoryA; delete factoryB; delete productA; delete productB; return 1; }新添加一个产品C只用,添加ConcreteProductC和ConcreteFactoryC,但是不用去修改已经存在的类,符合封闭-开放原则的封闭原则。
说明: 优点:工厂方法模式将创建对象的工作推迟到子类,使得系统易于扩展,可以通过添加新的具体工厂来支持新产品。缺点:每增加一种新产品,都需要增加一个新的工厂类,系统类的数量会迅速增加。 3. 抽象工厂模式(Abstract Factory Pattern)定义:
抽象工厂模式提供一个接口,用于创建**一系列**相关或依赖的对象,而无需指定它们具体的类。允许创建一组相关的对象(产品族),而每个具体的工厂都负责创建一组产品。常用于产品族的创建,即一组相互关联的对象的创建(比如跨平台 GUI 界面的不同风格)。 示例:
我们有两种平台(Windows 和 Linux),每个平台有不同的按钮和输入框。抽象工厂模式通过平台工厂来创建相应的控件。
#include <iostream> // 按钮接口 class Button { public: virtual void render() = 0; virtual ~Button() = default; }; // 输入框接口 class TextField { public: virtual void render() = 0; virtual ~TextField() = default; }; // 具体按钮类:Windows class WindowsButton : public Button { public: void render() override { std::cout << "Rendering Windows Button" << std::endl; } }; // 具体按钮类:Linux class LinuxButton : public Button { public: void render() override { std::cout << "Rendering Linux Button" << std::endl; } }; // 具体输入框类:Windows class WindowsTextField : public TextField { public: void render() override { std::cout << "Rendering Windows TextField" << std::endl; } }; // 具体输入框类:Linux class LinuxTextField : public TextField { public: void render() override { std::cout << "Rendering Linux TextField" << std::endl; } }; // 抽象工厂接口 class GUIFactory { public: virtual Button* createButton() = 0; virtual TextField* createTextField() = 0; /* 父类析构函数为虚函数的原因:在多态情况下正确地执行派生类的析构操作 */ virtual ~GUIFactory() = default; }; // 具体工厂类:Windows class WindowsFactory : public GUIFactory { public: Button* createButton() override { return new WindowsButton(); } TextField* createTextField() override { return new WindowsTextField(); } }; // 具体工厂类:Linux class LinuxFactory : public GUIFactory { public: Button* createButton() override { return new LinuxButton(); } TextField* createTextField() override { return new LinuxTextField(); } }; int main() { GUIFactory* factory = new WindowsFactory(); Button* button = factory->createButton(); TextField* textField = factory->createTextField(); button->render(); // 输出: Rendering Windows Button textField->render(); // 输出: Rendering Windows TextField delete button; delete textField; delete factory; factory = new LinuxFactory(); button = factory->createButton(); textField = factory->createTextField(); button->render(); // 输出: Rendering Linux Button textField->render(); // 输出: Rendering Linux TextField delete button; delete textField; delete factory; return 0; }说明:
优点:能够**创建一系列**相关的产品,客户端不需要知道具体类的实现,只需依赖工厂接口。缺点:增加了接口和类的数量,如果产品种类过多,抽象工厂可能变得复杂。 4. 工厂方法模式与抽象工厂模式的区别 特性工厂方法模式(Factory Method)抽象工厂模式(Abstract Factory)创建对象的方式每个工厂方法只负责创建一个具体产品。创建一系列相关或依赖的产品,通常创建多个产品。产品的数量通常每个工厂类创建一个产品。每个工厂类负责创建多个产品(一个产品族)。工厂的数量每个具体工厂类负责创建一个特定的产品。每个具体工厂类负责创建一系列相关的产品。产品的关系产品之间没有严格的依赖关系。产品之间通常有一定的关联,属于同一个产品族(如同一平台下的按钮和文本框)。扩展性新产品需要新建一个工厂类来负责创建它。新产品族需要新建一个工厂类来创建一组相关产品。适用场景产品种类不多时,或者系统只需要创建单一类型的对象时。当需要创建多个相关产品时,尤其是多个产品属于同一产品族时。总结:
工厂方法模式关注于**单一产品**的创建,每个具体工厂负责创建一个特定的产品。适用于产品种类少且扩展简单的场景。抽象工厂模式关注于**一系列相关产品**的创建,每个具体工厂负责创建多个相关的产品,适用于需要创建多个相关对象并保证它们兼容的场景,如跨平台的 UI 库。两者的主要区别在于创建产品的数量和产品之间的关系,工厂方法模式偏向于单一产品的创建,而抽象工厂模式偏向于创建一系列相关的产品。