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

工厂模式

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

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

简单工厂模式

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

#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;
}

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

工厂方法模式

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

#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;
}

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

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

抽象工厂模式

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

#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;
}

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

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

你可能感兴趣的:(#,创建型设计模式,设计模式)