当前位置: 首页 > article >正文

如何实现工厂模式?

概念

工厂模式(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):实现产品创建方法,返回平台特定的产品。
  • 客户端代码:可以轻松切换工厂,实现不同平台的界面。

总结

工厂模式通过提供一个接口来创建对象,将对象的创建过程与使用解耦。简单工厂适合小型应用,工厂方法模式适合需要扩展性和可维护性的应用,而抽象工厂模式适合复杂的产品系列。根据具体需求选择合适的工厂模式可以提高代码的灵活性和可维护性。


http://www.kler.cn/a/444814.html

相关文章:

  • Android详解——ConstraintLayout约束布局
  • Map.put 方法
  • day5,数据结构,单向,双向,循环链表
  • MCU驱动使用
  • 顺序表的操作
  • Ubuntu下C语言操作kafka示例
  • 服务器数据恢复—V7000存储中多块磁盘出现故障导致业务中断的数据恢复案例
  • 【python】OpenCV—Image Moments
  • 【DevOps工具篇】Jenkins的Pipeline(流水线)和Shared Library(共通库)
  • 基于Spring Boot的水果蔬菜商城系统
  • 写定制程序容易遇见的问题(FLASH不够时)
  • ArcGIS Pro 3.4新功能2:Spatial Analyst新特性,密度、距离、水文、太阳能、表面、区域分析
  • 功能篇:JAVA8实现数据去重
  • API网关基础知识
  • 怎麼在模擬器中實現換IP
  • pyQt5基本需求v1.0
  • C语言基础(五)【控制语句与循环综合应用篇猜数字游戏】
  • gcd 生成4d
  • 关于如何做技术文档
  • Android Java Ubuntu系统如何编译出 libopencv_java4.so
  • Linux文件属性 -- 文件大小
  • Suno Api V4模型无水印开发「续写」 —— 「Suno Api系列」第4篇
  • 自动图像标注可体验
  • day24文件操作--标准IO
  • 前端项目发布后打开报错Uncaught SyntaxError: Unexpected token ‘<‘ (at chunk-vendors)
  • 微信小程序实现画板画布自由绘制、选择画笔粗细及颜色、记录撤回、画板板擦、清空、写字板、导出绘图、canvas,开箱即用