设计模式--简单工厂模式


概念

简单工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪个类。在C++中,简单工厂模式可以通过一个工厂类来实现,该工厂类负责根据输入参数创建不同的对象实例。下面是一个简单的C++示例来说明简单工厂模式的实现:

#include <iostream>
using namespace std;

// 定义一个抽象的产品类
class Product {
public:
    virtual void use() = 0;
};

// 具体的产品类A
class ConcreteProductA : public Product {
public:
    void use() {
        cout << "Using Product A" << endl;
    }
};

// 具体的产品类B
class ConcreteProductB : public Product {
public:
    void use() {
        cout << "Using Product B" << endl;
    }
};

// 简单工厂类
class SimpleFactory {
public:
    Product* createProduct(int type) {
        if (type == 1) {
            return new ConcreteProductA();
        } else if (type == 2) {
            return new ConcreteProductB();
        } else {
            return nullptr;
        }
    }
};

int main() {
    SimpleFactory factory;
    Product* productA = factory.createProduct(1);
    Product* productB = factory.createProduct(2);

    productA->use();
    productB->use();

    delete productA;
    delete productB;

    return 0;
}

在上面的示例中,我们定义了一个抽象的产品类 Product,并创建了两个具体的产品类 ConcreteProductAConcreteProductB。然后,我们实现了一个简单工厂类 SimpleFactory,它根据输入的参数来创建不同的产品实例。在 main 函数中,我们使用简单工厂来创建产品实例,并调用其方法。

这就是C++中简单工厂模式的基本实现。通过这种方式,客户端代码可以通过简单工厂类来创建产品对象,而无需直接实例化具体的产品类。


使用场景

在C++中,简单工厂模式通常在以下场景中使用:

  1. 对象的创建逻辑相对简单:当需要创建的对象的逻辑相对简单,不涉及复杂的条件判断或算法时,简单工厂模式是一个很好的选择。

  2. 需要隐藏对象创建细节:简单工厂模式可以将对象的创建逻辑封装在工厂类中,客户端代码无需了解具体的对象创建细节,只需要通过工厂类来获取所需的对象实例。

  3. 降低耦合度:通过简单工厂模式,客户端代码与具体产品类之间的耦合度降低,因为客户端只需要与工厂类进行交互,而不需要直接依赖具体的产品类。

  4. 需要统一管理对象的创建:如果系统中需要统一管理对象的创建过程,可以使用简单工厂模式来集中管理对象的创建逻辑,便于维护和管理。

总的来说,简单工厂模式适合于对象创建逻辑相对简单、需要隐藏对象创建细节、降低耦合度以及统一管理对象创建的场景。通过工厂类统一管理对象的创建,可以提高代码的灵活性和可维护性。


示例

类图

代码实现

#include <iostream>
#include <map>
#include <memory>
using namespace std;

// 抽象运算类
class Operation {
public:
    virtual double GetResult() {
        return 0;
    }
    double NumberA;
    double NumberB;
};

// 加法类,继承运算类
class OperationAdd : public Operation {
    double GetResult() {
        return this->NumberA + this->NumberB;
    }
};

// 减法类,继承运算类
class OperationSub : public Operation {
    double GetResult() {
        return this->NumberA - this->NumberB;
    }
};

// 乘法类,继承运算类
class OperationMul : public Operation {
    double GetResult() {
        return this->NumberA * this->NumberB;
    }
};

// 除法类,继承运算类
class OperationDiv : public Operation {
    double GetResult() {
        return this->NumberA / this->NumberB;
    }
};

map<string, int> calc_map = {
    {"+", 0},
    {"-", 1},
    {"*", 2},
    {"/", 3},
};

// 简单工厂类
// 只需要输入运算符号,工厂就实例化出合适的对象,通过多态(动态多态:重写)返回父类的方式实现计算器的结果
class OperationFactory {
public:
    static Operation* creationOperation(string operate) {
        Operation *op = nullptr;
        switch(int(calc_map[operate])) {
            case 0:
                op = new OperationAdd();
                break;
            case 1:
                op = new OperationSub();
                break;
            case 2:
                op = new OperationMul();
                break;
            case 3:
                op = new OperationDiv();
                break;
        }
        return op;
    }
};

int main() {
    unique_ptr<Operation> oper(OperationFactory::creationOperation("+"));
    // Operation *oper = OperationFactory::creationOperation("+");
    oper->NumberA = 10;
    oper->NumberB = 2;
    double result = oper->GetResult();
    cout << "result = " << result << endl;

    unique_ptr<Operation> oper2(OperationFactory::creationOperation("-"));
    oper2->NumberA = 10;
    oper2->NumberB = 2;
    double result2 = oper2->GetResult();
    cout << "result2 = " << result2 << endl;

    unique_ptr<Operation> oper3(OperationFactory::creationOperation("*"));
    oper3->NumberA = 10;
    oper3->NumberB = 2;
    double result3 = oper3->GetResult();
    cout << "result3 = " << result3 << endl;

    unique_ptr<Operation> oper4(OperationFactory::creationOperation("/"));
    oper4->NumberA = 10;
    oper4->NumberB = 2;
    double result4 = oper4->GetResult();
    cout << "result4 = " << result4 << endl;

    
    return 0;
}

/*
result = 12
result2 = 8
result3 = 20
result4 = 5
*/
posted @ 2024-01-15 17:36  guanyubo  阅读(16)  评论(0编辑  收藏  举报