【设计模式】简单工厂模式

C语言实现简单的工厂模式

c 复制代码
#include <stdio.h>
#include <stdlib.h>

// 图形类型枚举
typedef enum {
    CIRCLE,
    SQUARE,
    RECTANGLE
} ShapeType;

// 图形结构体
typedef struct {
    ShapeType type;
    float area;
} Shape;

// 创建圆形
Shape* createCircle() {
    Shape* circle = (Shape*)malloc(sizeof(Shape));
    circle->type = CIRCLE;
    circle->area = 0.0;
    return circle;
}

// 创建正方形
Shape* createSquare() {
    Shape* square = (Shape*)malloc(sizeof(Shape));
    square->type = SQUARE;
    square->area = 0.0;
    return square;
}

// 创建长方形
Shape* createRectangle() {
    Shape* rectangle = (Shape*)malloc(sizeof(Shape));
    rectangle->type = RECTANGLE;
    rectangle->area = 0.0;
    return rectangle;
}

// 工厂方法根据类型创建图形
Shape* createShape(ShapeType type) {
    switch (type) {
        case CIRCLE:
            return createCircle();
        case SQUARE:
            return createSquare();
        case RECTANGLE:
            return createRectangle();
        default:
            return NULL;
    }
}

int main() {
    Shape* circle = createShape(CIRCLE);
    Shape* square = createShape(SQUARE);
    Shape* rectangle = createShape(RECTANGLE);

    // 假设这里对图形对象进行了一些操作

    // 释放内存
    free(circle);
    free(square);
    free(rectangle);

    return 0;
}

C++实现简单的工厂模式

cpp 复制代码
#include <iostream>

// 图形类型枚举
enum class ShapeType {
    CIRCLE,
    SQUARE,
    RECTANGLE
};

// 图形基类
class Shape {
public:
    virtual ~Shape() {}
    virtual float getArea() = 0;
};

// 圆形类
class Circle : public Shape {
public:
    Circle() {
        std::cout << "Creating Circle..." << std::endl;
    }

    float getArea() override {
        std::cout << "Calculating Circle Area..." << std::endl;
        // 计算圆形面积的具体实现
        return 0.0;
    }
};

// 正方形类
class Square : public Shape {
public:
    Square() {
        std::cout << "Creating Square..." << std::endl;
    }

    float getArea() override {
        std::cout << "Calculating Square Area..." << std::endl;
        // 计算正方形面积的具体实现
        return 0.0;
    }
};

// 长方形类
class Rectangle : public Shape {
public:
    Rectangle() {
        std::cout << "Creating Rectangle..." << std::endl;
    }

    float getArea() override {
        std::cout << "Calculating Rectangle Area..." << std::endl;
        // 计算长方形面积的具体实现
        return 0.0;
    }
};

// 图形工厂类
class ShapeFactory {
public:
    static Shape* createShape(ShapeType type) {
        switch (type) {
            case ShapeType::CIRCLE:
                return new Circle();
            case ShapeType::SQUARE:
                return new Square();
            case ShapeType::RECTANGLE:
                return new Rectangle();
            default:
                std::cout << "Invalid Shape Type!" << std::endl;
                return nullptr;
        }
    }
};

int main() {
    Shape* circle = ShapeFactory::createShape(ShapeType::CIRCLE);
    Shape* square = ShapeFactory::createShape(ShapeType::SQUARE);
    Shape* rectangle = ShapeFactory::createShape(ShapeType::RECTANGLE);

    // 假设这里对图形对象进行了一些操作

    // 删除对象,避免内存泄漏
    delete circle;
    delete square;
    delete rectangle;

    return 0;
}

工厂模式的优缺点:

优点:

封装对象的创建 :工厂模式将对象的创建过程封装在工厂类中,客户端代码无需直接调用构造函数来创建对象,从而降低了代码耦合度。
易于扩展 :如果需要添加新类型的产品(图形),只需要添加一个新的产品类和对应的工厂方法即可,不需要修改现有代码,符合开闭原则。
屏蔽具体实现 :客户端只需与抽象产品和抽象工厂进行交互,不关心具体的产品类和工厂类,隐藏了产品对象的具体实现。
创建对象的集中管理 :所有产品的创建都在工厂类中,便于统一管理和维护。
容易调试:通过在工厂方法中添加打印语句,可以方便地观察对象的创建过程和其他信息,便于调试。

缺点:

增加了类的个数 :每个具体产品都需要一个对应的具体工厂类,如果产品较多,会增加类的数量,增加系统复杂性。
增加了系统抽象性 :引入工厂类和抽象产品,增加了系统的抽象性和理解难度,增加开发难度。
不易理解 :工厂模式的代码会比直接创建对象的方式复杂,理解起来可能会有一定困难。
可能造成额外开销:在运行时使用工厂方法创建对象可能会比直接使用构造函数创建对象稍微慢一些,因为需要进行动态内存分配。但在实际应用中,这个开销通常是可以忽略不计的。

综上所述,工厂模式是一种灵活且可扩展的设计模式,它通过封装对象的创建过程,帮助我们降低代码的耦合度,并支持系统的扩展和维护。工厂模式适用于需要在运行时动态创建对象的场景,例如创建不同类型的图形、产品、对象等。通过工厂模式,我们可以更加灵活地管理对象的创建,使代码结构更加清晰和易于维护。

然而,工厂模式也有一些局限性,例如增加了类的数量和抽象性,可能会增加代码的复杂性和理解难度。在使用工厂模式时,需要根据实际情况来选择合适的设计方案,避免过度设计。对于简单的应用场景,直接使用构造函数创建对象可能更为简单和直观。

总的来说,工厂模式是一种有用的设计模式,它在合适的场景下可以为我们提供更好的设计和代码组织结构。对于复杂的系统,特别是涉及到大量对象创建和管理的情况,工厂模式可以发挥更大的优势。在实际项目中,根据具体需求和复杂度选择是否使用工厂模式是很重要的。

相关推荐
UIU1148 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场8 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi8 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David9 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院10 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng10 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
j7~13 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py14 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing14 小时前
LeetCode100 42.接雨水
java·算法·leetcode
域限奇点访客15 小时前
用AI生成问卷的网站怎么选?看题目录入结构、题型映射和生成后的校验
算法