• 【设计模式】工厂模式总结


    工厂模式

    定义一个创建对象的接口,让子类决定实例化哪个类,而对象的创建统一交由工厂去生产。

    工厂模式大致可以分为三类:简单工厂模式、工厂方法模式、抽象工厂模式

    简单工厂模式

    简单工厂模式提供一个工厂类,根据传入的参数来创建不同类型的对象,而客户端代码无需了解对象的创建过程。

    #include 
    
    // 基类,所有图形对象的父类
    class Shape {
    public:
        virtual void draw() = 0;
    };
    
    // 具体的圆形类
    class Circle : public Shape {
    public:
        void draw() {
            std::cout << "Draw a circle" << std::endl;
        }
    };
    
    // 具体的矩形类
    class Rectangle : public Shape {
    public:
        void draw() {
            std::cout << "Draw a rectangle" << std::endl;
        }
    };
    
    // 简单工厂类
    class ShapeFactory {
    public:
        // 根据传入的参数创建不同类型的图形对象
        Shape* createShape(const std::string& shapeType) {
            if (shapeType == "circle") {
                return new Circle();
            } else if (shapeType == "rectangle") {
                return new Rectangle();
            } else {
                return nullptr; // 可以添加错误处理逻辑
            }
        }
    };
    
    int main() {
        ShapeFactory factory;
        
        // 创建圆形对象
        Shape* circle = factory.createShape("circle");
        if (circle) {
            circle->draw();
            delete circle;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    缺点:增加新类型时需要修改工厂类,违反开闭原则。

    工厂方法模式

    工厂方法模式定义了一个创建对象的接口,但将具体对象的创建交给子类来实现。

    #include 
    #include 
    
    // 抽象产品类:文档
    class Document {
    public:
        virtual void open() = 0;
        virtual void save() = 0;
    };
    
    // 具体产品类:PDF 文档
    class PDFDocument : public Document {
    public:
        void open() {
            std::cout << "Opening a PDF document" << std::endl;
        }
    
        void save() {
            std::cout << "Saving a PDF document" << std::endl;
        }
    };
    
    // 具体产品类:文本文档
    class TextDocument : public Document {
    public:
        void open() {
            std::cout << "Opening a Text document" << std::endl;
        }
    
        void save() {
            std::cout << "Saving a Text document" << std::endl;
        }
    };
    
    // 抽象工厂类
    class DocumentFactory {
    public:
        virtual Document* createDocument() = 0;
    };
    
    // 具体工厂类:PDF 文档工厂
    class PDFDocumentFactory : public DocumentFactory {
    public:
        Document* createDocument() {
            return new PDFDocument();
        }
    };
    
    // 具体工厂类:文本文档工厂
    class TextDocumentFactory : public DocumentFactory {
    public:
        Document* createDocument() {
            return new TextDocument();
        }
    };
    
    int main() {
        DocumentFactory* factory = nullptr;
        Document* doc = nullptr;
    
        // 创建 PDF 文档
        factory = new PDFDocumentFactory();
        doc = factory->createDocument();
        doc->open();
        doc->save();
        delete doc;
        delete factory;
    
        // 创建文本文档
        factory = new TextDocumentFactory();
        doc = factory->createDocument();
        doc->open();
        doc->save();
        delete doc;
        delete factory;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    优点: 扩展性好,符合了开闭原则, 新增一种产品时,只需增加改对应的产品类和对应的工厂子类即可。

    缺点:每增加一种新类型,就需要增加一个对象的工厂; 相比简单工厂模式,工厂方法模式需要更多的类定义。

    抽象工厂模式

    抽象工厂模式允许你创建一系列相关的对象,而不指定具体的类。

    #include 
    #include 
    
    // 抽象产品类:按钮
    class Button {
    public:
        virtual void render() = 0;
    };
    
    // 具体产品类:Windows按钮
    class WindowsButton : public Button {
    public:
        void render() {
            std::cout << "Rendering a Windows button" << std::endl;
        }
    };
    
    // 具体产品类:Linux按钮
    class LinuxButton : public Button {
    public:
        void render() {
            std::cout << "Rendering a Linux button" << std::endl;
        }
    };
    
    // 抽象产品类:窗口
    class Window {
    public:
        virtual void createButton() = 0;
    };
    
    // 具体产品类:Windows窗口
    class WindowsWindow : public Window {
    public:
        void createButton() {
            Button* button = new WindowsButton();
            button->render();
        }
    };
    
    // 具体产品类:Linux窗口
    class LinuxWindow : public Window {
    public:
        void createButton() {
            Button* button = new LinuxButton();
            button->render();
        }
    };
    
    // 抽象工厂类
    class GUIFactory {
    public:
        virtual Window* createWindow() = 0;
    };
    
    // 具体工厂类:Windows工厂
    class WindowsGUIFactory : public GUIFactory {
    public:
        Window* createWindow() {
            return new WindowsWindow();
        }
    };
    
    // 具体工厂类:Linux工厂
    class LinuxGUIFactory : public GUIFactory {
    public:
        Window* createWindow() {
            return new LinuxWindow();
        }
    };
    
    int main() {
        GUIFactory* factory = nullptr;
        Window* window = nullptr;
    
        // 创建Windows风格的窗口和按钮
        factory = new WindowsGUIFactory();
        window = factory->createWindow();
        delete factory;
    
        // 创建Linux风格的窗口和按钮
        factory = new LinuxGUIFactory();
        window = factory->createWindow();
        delete factory;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    优点: 工厂抽象类创建了多个类型的产品,当有需求时,可以创建相关产品子类和子工厂类来获取。

    缺点: 需要在抽象工厂类中提前确定可能需要的产品种类,以满足不同型号的多种产品的需求;如果我们需要的产品种类并没有在抽象工厂类中提前确定,则需要修改抽象工厂类了,以及所有的工厂子类。

  • 相关阅读:
    Codeforces Round #804 (Div. 2)(A~D)
    宠物衣服类和宠物玩具类上架亚马逊CPC检测标准
    使用Node.js搭建服务器
    猿创征文 |【JavaScript】-- js知识点大总结
    pandas第8章-文本数据
    webpack打包js文件
    【Leetcode Sheet】Weekly Practice 11
    Linux内核宏Container_Of
    pdf文件怎么转化为word,pdf转换成word的方法
    高通导航器软件开发包使用指南(12)
  • 原文地址:https://blog.csdn.net/m0_70195913/article/details/134242580