C++设计模式之简单工厂模式实例

C++设计模式之简单工厂模式实例详解

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。简单工厂模式定义了一个工厂类,它可以根据所传递的参数或配置文件的不同,返回不同类的实例。简单工厂模式具有简单易懂,适用范围广等特点,在实际开发中也得到了广泛应用。

简单工厂模式的结构

简单工厂模式包含三个主要角色:

  • 工厂类:简单工厂模式的核心,负责创建所有产品的实例。
  • 抽象产品类:定义产品的接口,是具体产品的基类。
  • 具体产品类:实现抽象产品类的接口,是被创建的对象。

简单工厂模式的结构图:

+------------+
|  Factory   |
+------------+
| createProd |
+------------+
       |
       | 实例化产品对象
       |
+------------+             +---------------+
| Product    | <---------  | ConcreteProd1 |
+------------+             +---------------+
| method1()  |             | method1()     |
| method2()  |             | method2()     |
+------------+             +---------------+
              实现

+------------+             +---------------+
| Product    | <---------  | ConcreteProd2 |
+------------+             +---------------+
| method1()  |             | method1()     |
| method2()  |             | method2()     |
+------------+             +---------------+

简单工厂模式示例

下面通过两个实例来详细介绍简单工厂模式的应用。

示例一:计算器程序

在计算器程序中,我们传递了两个数和运算符,根据运算符的不同返回不同的计算结果。通过使用简单工厂模式,我们可以实现这个过程。

首先,定义抽象产品类 Operation,其中定义了两个虚函数 getResult()setNum(),分别用于计算结果和设置操作数。

class Operation {
public:
    virtual double getResult() = 0;
    virtual void setNum(double a, double b) {
        numA = a;
        numB = b;
    }
protected:
    double numA;
    double numB;
};

然后,定义两个具体产品类 AddOperationSubOperation,分别实现抽象产品类的接口。在具体产品类中,我们可以实现具体的计算逻辑。

class AddOperation: public Operation
{
public:
    double getResult() override {
        return numA + numB;
    }
};

class SubOperation: public Operation
{
public:
    double getResult() override {
        return numA - numB;
    }
};

最后,定义工厂类 Factory,根据运算符的不同返回不同的产品实例。在工厂类中,我们使用了 switch 语句来判断运算符类型。

class Factory
{
public:
    static Operation* createOperation(char operate)
    {
        Operation* oper = nullptr;
        switch (operate) {
            case '+':
                oper = new AddOperation();
                break;
            case '-':
                oper = new SubOperation();
                break;
            default:
                cout << "invalid operate!" << endl;
                break;
        }
        return oper;
    }
};

在客户端中,我们可以通过如下代码调用工厂类,创建对应产品的实例,并调用其接口函数。

int main() {
    Operation* op = Factory::createOperation('+');
    op->setNum(1, 2);
    cout << op->getResult() << endl;
    return 0;
}

示例二:图形画笔程序

在图形画笔程序中,我们传递了一个图形类型,根据类型的不同返回不同绘制图形的画笔。同样通过使用简单工厂模式,我们可以实现这个过程。

首先,我们定义了工具类 Point,用于表示一个点。然后,定义抽象产品类 Shape,其中定义了两个纯虚函数 draw()setPoint(),分别用于绘制图形和设置绘制点。

class Shape
{
public:
    virtual void draw() = 0;
    virtual void setPoint(Point p) = 0;

protected:
    Point m_point;
};

class Point
{
public:
    Point(int x = 0, int y = 0) : m_x(x), m_y(y) {}
    void setPoint(int x, int y) { m_x = x; m_y = y; }
    void setX(int x) { m_x = x; }
    void setY(int y) { m_y = y; }
    int x() const { return m_x; }
    int y() const { return m_y; }
private:
    int m_x;
    int m_y;
};

然后,定义不同的具体产品类:LineShapeCircleShapeSquareShape,分别实现抽象产品类的接口。在每个具体产品类中,我们按照不同的逻辑实现具体的图形绘制过程。

// 按照覆盖父类的虚函数来实现具体产品类
class LineShape: public Shape
{
public:
    void draw() override {
        cout << "draw line from (" << m_point.x() << ", " << m_point.y() << ")" << endl;
    }
    void setPoint(Point p) override {
        m_point = p;
    }
};

class CircleShape: public Shape
{
public:
    void draw() override {
        cout << "draw circle with center (" << m_point.x() << ", " << m_point.y() << ")" << endl;
    }
    void setPoint(Point p) override {
        m_point = p;
    }
};

class SquareShape: public Shape
{
public:
    void draw() override {
        cout << "draw square with center (" << m_point.x() << ", " << m_point.y() << ")" << endl;
    }
    void setPoint(Point p) override {
        m_point = p;
    }
};

最后,定义工厂类 ShapeFactory,根据传入的参数类型返回不同的产品实例。在工厂类中,我们使用了 switch 语句来判断图形类型。

class ShapeFactory
{
public:
    static Shape* createShape(int type)
    {
        Shape* shape;
        switch (type) {
            case 1:
                shape = new LineShape();
                break;
            case 2:
                shape = new CircleShape();
                break;
            case 3:
                shape = new SquareShape();
                break;
            default:
                cout << "invalid shape!" << endl;
                shape = nullptr;
                break;
        }
        return shape;
    }
};

在客户端中,我们可以通过如下代码调用工厂类,创建对应产品的实例,并调用其接口函数。

int main() {
    Shape* shape1 = ShapeFactory::createShape(1);
    shape1->setPoint(Point(1, 1));
    shape1->draw();
    Shape* shape2 = ShapeFactory::createShape(2);
    shape2->setPoint(Point(2, 2));
    shape2->draw();
    Shape* shape3 = ShapeFactory::createShape(3);
    shape3->setPoint(Point(3, 3));
    shape3->draw();
    return 0;
}

总结

简单工厂模式可以方便地创建一些对象,减少了代码重复和耦合度。但是简单工厂模式有些缺点,在实现时需要考虑到可扩展性和可维护性问题。因为增加新产品需要修改工厂类的代码,这样会违背开放封闭原则。所以在实际项目中需要根据实际情况选用不同的设计模式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++设计模式之简单工厂模式实例 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C程序 将以英寸-英尺为单位的N个距离相加

    可以使用以下步骤完成C程序 将以英寸-英尺为单位的N个距离相加: 步骤一:定义距离变量和变量总数 首先需要定义变量来保存距离和距离总数,可以使用float类型来保存距离,int类型来保存距离总数,例如: int n; // 距离总数 float distance; // 单位为英尺或英寸的距离 步骤二:输入距离 使用循环结构来输入所有距离,例如: for(i…

    C 2023年5月9日
    00
  • C语言利用sprintf固定字符串输出位数

    C语言中常用的输出函数是printf,该函数可以输出各种类型的数据,但是无法固定输出的长度。如果想要输出固定长度的字符串,可以使用sprintf函数。本文将详细讲解sprintf固定字符串输出位数的攻略。 sprintf函数概述 sprintf是C语言中的输出函数,其原型为: int sprintf(char *str, const char *format…

    C 2023年5月22日
    00
  • windows中使用icacls命令还原文件夹的权限设置

    下面是详细讲解“windows中使用icacls命令还原文件夹的权限设置”的完整攻略。 一、什么是icacls命令 icacls命令是Windows系统中的一个命令行工具,它可以帮助我们管理文件和文件夹的访问控制列表(ACL)。ACL是指访问控制列表,用于控制文件和文件夹对用户或用户组的访问权限。 二、使用icacls命令还原文件夹的权限设置 当我们遇到Wi…

    C 2023年5月23日
    00
  • C++实现STL迭代器萃取的示例代码

    一、什么是迭代器萃取? 迭代器萃取是一种通过编译时模板元编程技术,获取迭代器类型相关信息的方法。例如,获取迭代器的 value_type、iterator_category、difference_type 和 pointer 等信息。通过迭代器萃取,我们可以更加精确地对各种类型的迭代器进行操作,并且提供更高的泛型性和可重用性。 迭代器萃取一般通过 C++ S…

    C 2023年5月24日
    00
  • C语言中如何进行代码优化?

    代码优化是提高程序性能和运行效率的必要手段,也是编程中一个重要的环节。C语言中进行代码优化可以采取如下措施: 1. 优化算法 在编程中,算法的选择对程序性能影响较大,常见的提高算法效率的方法有: 1.1 使用空间换时间的算法 如果内存空间充足的情况下,可以采用空间复杂度高但时间复杂度低的算法,避免使用时间复杂度高但空间复杂度低的算法,从而提高程序性能。 例如…

    C 2023年4月27日
    00
  • 详解NodeJS模块化

    下面我将详细讲解“详解NodeJS模块化”的完整攻略。 一、NodeJS模块化的基础知识 在 NodeJS 中,每个文件都被视作一个模块,每个模块都具有独立的作用域和命名空间,模块之间的变量和函数是相互独立的。在 NodeJS 中,一个模块可以通过 require 函数引入另一个模块的功能,从而实现模块化开发。NodeJS 支持 CommonJS 规范,因此…

    C 2023年5月23日
    00
  • Go语言中JSON文件的读写操作

    让我为你详细讲解Go语言中JSON文件的读写操作的完整攻略。 什么是JSON? JSON(JavaScript Object Notation),是一种轻量级的数据交换格式,它易于人阅读和编写,同时也易于机器解析和生成。JSON与XML的区别,它是纯文本,更容易阅读,而且数据结构也很简单。在Web开发中,JSON数据是一种非常常见的数据格式。 Go语言中JS…

    C 2023年5月23日
    00
  • C++分步实现职工管理系统详解

    C++分步实现职工管理系统详解攻略 1. 程序基本框架 职工管理系统可以分为三个类别:员工基本信息类(Employee),普通员工类(Worker)和经理类(Manager)。其中,普通员工类和经理类都继承了员工基本信息类,因此程序框架如下: // 员工信息类 class Employee { public: virtual void showInfo() …

    C 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部