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 判断

    当在编写 C 语言程序时,我们可能需要使用判断语句来根据条件执行不同的代码块。C 中有三种不同的判断语句:if 语句、switch 语句以及三目运算符。在这里,我将详细讲解这三种判断语句的使用方法和语法规则。 if 语句 if 语句允许我们对一个条件进行测试,并根据测试结果决定是否执行某个代码块。其基本语法如下: if (条件) { 需要执行的代码块 } 其…

    C 2023年5月10日
    00
  • 浅析C++内存布局

    浅析C++内存布局 C++是一门面向过程的编程语言,与其他编程语言一样,C++也有自己的内存布局。 内存布局基本概念 堆 使用new或malloc操作后存放动态分配的数据的区域。 栈 用于存放程序运行时的函数栈帧,栈帧将在函数执行完后自行清除。 全局变量区 在程序运行前就分配好的存放全局变量的区域,该区域分为静态区和可读写区。 常量区 存放程序中常量的区域,…

    C 2023年5月22日
    00
  • C语言实现简单猜数字小游戏

    C语言实现简单猜数字小游戏攻略 游戏规则 在这个简单的猜数字小游戏中,计算机会随机生成一个1到100之间的数字,玩家需要通过不断猜测来猜出这个数字。每猜一个数字,计算机都会告诉玩家这个数字是猜大了还是猜小了,直到玩家猜中为止。 实现步骤 步骤一:获取随机数 使用C语言标准库stdlib.h中的rand()函数来获取一个1到100之间的随机数,这可以通过调用r…

    C 2023年5月23日
    00
  • 如何在C++中调用python代码你知道吗

    当我们需要在 C++ 项目中调用 Python 代码时,可以通过内置的 Python 解释器来实现。以下是在 C++ 中使用 Python 的完整攻略: 步骤一:安装Python解释器 首先需要安装 Python 解释器。我们可以从官网下载并安装最新版本的 Python,也可以使用 Anaconda 等发行版。安装完成之后,需要将 Python 的路径添加到…

    C 2023年5月23日
    00
  • C语言实现散列表(哈希Hash表)实例详解

    下面我将为您详细讲解“C语言实现散列表(哈希Hash表)实例详解”的完整攻略。 概述 哈希(Hash)是一种能够快速定位存储位置的技术。哈希表(Hash Table)也叫散列表,是利用哈希函数(Hash Function)进行访问的数据结构。C语言中的哈希表主要分为两种:开放地址法和链表法。 开放地址法又分为线性探测法、二次探测法和双重散列法。本文主要介绍使…

    C 2023年5月23日
    00
  • STL 的string类怎么啦

    下面我将为您详细讲解STL的string类的使用方法: STL的string类 string类是STL中的一个重要组件,它是一个可变长度的字符串容器,支持字符串的插入、删除、查找、替换等操作。可以通过#include <string>来包含string类的头文件。 创建string对象 我们可以通过多种方式来创建string对象。比如: // 创…

    C 2023年5月23日
    00
  • C++实现路口交通灯模拟系统

    C++实现路口交通灯模拟系统完整攻略 介绍 本系统利用C++语言实现,模拟了路口交通灯的控制,包括车辆的停止和通行,交通信号的改变等。系统结构清晰,代码简单易懂,适合初学者学习C++语言的基础和面向对象编程的实现。 设计思路 本系统的设计思路涉及到面向对象编程的基本思想。首先将路口、红绿灯、车辆等实体抽象为类,通过类的成员函数实现对对象的控制。同时,本系统利…

    C 2023年5月23日
    00
  • Java Exception异常全方面分析

    Java Exception异常全方面分析 Java中异常是程序运行中发生的错误或者异常情况的标志,有时我们无法避免由于代码本身的错误或者外在因素导致程序发生异常。因此,掌握异常的相关知识,在开发过程中是非常必要的。 本文将全方面地讲解Java中异常的相关知识,包括异常的类型、异常处理、异常抛出与捕获等内容,旨在帮助Java开发者更好地理解和使用异常。 异常…

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