《大话设计模式》笔记——简单工厂模式

本文以C语言实现简单工厂模式,通过一个工厂函数创建不同的计算操作对象,如加、减、乘、除,提高代码的可读性和可扩展性。通过这种方式,避免了直接使用switch语句导致的代码耦合,增强了代码的层次感和可维护性。

前言

我(长胖的阿诏)是新入行的嵌入式程序员,所以用C语言做示例演示,我看到书上都是 C# 语言的代码,所以我只能先领会精神,再通过C语言复刻。在我的资源里好像没有见过用24k纯C语言来描述设计模式的例子的,所以我只能摸石头过河,如果有大牛看见我的 错误 还请劳烦指出,阿诏先行谢过。

这是同步更新的Gitee地址用于存放写过的源码文件:
https://gitee.com/auyvjpz/design-mode-notes.git


简单工厂模式

"我"的理解

简单工厂模式,顾名思义通过一个“工厂”可以生产出不同的用途的“东西”。

通过编写计算器时,我们需要面对多种计算方法的实现(加、减、乘、除等)。这时最直接的想法是通过switch去选择计算的模式,但是这样写会造成每种计算的代码耦合在一个switch的case组合中,只能说可以实现但是复用性不高。

而简单工厂模式抽象出一个“简单工厂的功能层”,通过“工厂”可以创建不同算法但执行过程相同的“功能对象”,从而应对不同计算方法的实现过程。

UML图解

OperationFactory依赖TOperation的子类创建不同TOperation功能对象

在这里插入图片描述

代码实现

// 简单工厂.c


//~~~~ 运算类 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

typedef enum TOperationTypeTag TOperationType;
enum TOperationTypeTag
{
    kOptAdd,
    kOptSub,
    kOptMul,
    kOptDiv,
}; ///< 每种计算符号枚举值

// 计算函数类型
typedef float (*TDoCalculate)(TOperation* AObj)

typedef struct 
{
    float        number1;  // 参与计算参数1
    float        number2;  // 参与计算参数2

    // 每个子类要实现的函数
    TDoCalculate __DoCalculate; 
} TOperation;

// 调用计算函数
float TOperationDoCalculate(TOperation* AObj)
{
    return AObj->__DoCalculate(AObj);
}

// 释放计算类
void TOperationFree(TOperation* AObj)
{
    if (AObj != NULL)
        free(AObj);
}

//~~~~~~~~~~~~~~~~~ 加法运算类 ~~~~~~~~~~~~~~~~~~~~~~~~~

typedef struct 
{
    TOperation parent;  // 继承计算父类
} TAddOperation;

static float L_AddDoCalculate(TOperation* AObj)
{
    return AObj->number1 + AObj->number2;
}

void* TAddOperationCreate()
{
    TAddOperation* obj = (TAddOperation*)malloc(sizeof(TAddOperation));
    
    if (obj != NULL)
        obj->__DoCalculate = L_AddDoCalculate;
    
    return (void*)obj;
}

//~~~~~~~~~~~~~~~~~ 减法运算类 ~~~~~~~~~~~~~~~~~~~~~~~~~

typedef struct 
{
    TOperation parent;  // 继承计算父类
} TSubOperation;

static float L_SubDoCalculate(TOperation* AObj)
{
    return AObj->number1 - AObj->number2;
}

void* TSubOperationCreate()
{
    TSubOperation* obj = (TSubOperation*)malloc(sizeof(TSubOperation));
    
    if (obj != NULL)
        obj->__DoCalculate = L_SubDoCalculate;
    
    return (void*)obj;
}

//~~~~~~~~~~~~~~~~~ 乘法运算类 ~~~~~~~~~~~~~~~~~~~~~~~~~

typedef struct 
{
    TOperation parent;  // 继承计算父类
} TMulOperation;

static float L_MulDoCalculate(TOperation* AObj)
{
    return AObj->number1 * AObj->number2;
}

void* TMulOperationCreate()
{
    TMulOperation* obj = (TMulOperation*)malloc(sizeof(TMulOperation));
    
    if (obj != NULL)
        obj->__DoCalculate = L_MulDoCalculate;
    
    return (void*)obj;
}

//~~~~~~~~~~~~~~~~~ 除法运算类 ~~~~~~~~~~~~~~~~~~~~~~~~~

typedef struct 
{
    TOperation parent;  // 继承计算父类
} TDivOperation;

static float L_DivDoCalculate(TOperation* AObj)
{
    return AObj->number1 / AObj->number2;
}

void* TDivOperationCreate()
{
    TDivOperation* obj = (TDivOperation*)malloc(sizeof(TDivOperation));
    
    if (obj != NULL)
        obj->__DoCalculate = L_DivDoCalculate;
    
    return (void*)obj;
}

//~~~~~~~~~~~~~~~~~ 运算工厂 ~~~~~~~~~~~~~~~~~~~~~~~~~

// 因为工厂只有一个create方法,所以可以直接以一个函数的形式存在
TOperation* OperationFactoryCreateOperation(int type)
{
    TOperation* result = NULL;
    
    switch (type)
    {
    case kOptAdd : 
        result = TAddOperationCreate();
        break;
    
    case kOptSub : 
        result = TSubOperationCreate();
        break;
    
    case kOptMul : 
        result = TMulOperationCreate();
        break;
    
    case kOptDiv : 
        result = TDivOperationCreate();
        break;  
        
    default :
        printf("暂不支持 %s 计算\n", GetOptTypeName(type));
    }
    
    return result;
}


//~~~~~~~~~~~~~~~~~ 使用示例 ~~~~~~~~~~~~~~~~~~~~~~~~~

int Test()
{

    // 选择计算方式
    TOperationType sign = InputOptType();
    // 创建对应计算对象
    TOperation* opt_obj = OperationFactoryCreateOperation(sign);
    
    if (opt_obj != NULL)
    {   
        opt_obj->number1 = InputFloat();  // 获取参数1
        opt_obj->number2 = InputFloat();  // 获取参数2
        
        float ret = TOperationDoCalculate(opt_obj);  // 得到计算结果
        printf("结果为:%f\n", ret);
        
        TOperationFree(opt_obj);  // 释放对象
    }   
    
    return 0;
}

总结

Q: 明明可以简单的用switch用5分钟写完,为什么花半小时敲这么多。

  • 首先,这样代码的层次感很强,用户(test函数编写者)只需要按照步骤一步步完成功能的实现。

  • 其次,如果需要修改某个计算可以很快的锁定需要改动的位置,修改完成后主函数不需要变动。

  • 然后,代码拓展性高,比如添加一个幂次的操作,只需要按照相同的方法复制一个子类即可,然后只在“工厂”中添加一条生产线(case 分支)即可,主函数依旧不需要动。

由此可知,简单工厂抽象了对象的行为,通过“工厂”的方式生产出具有不同行为的对象(这可能就是 多态 ),来执行相同的流程,得到不同的结果。

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来创建不同类型的对象,而无需暴露对象创建的逻辑给客户端。在Python中,简单工厂模式可以通过一个工厂类来创建不同的产品对象。下面是一个简单的示例: ```python class Product: def operation(self): pass class ConcreteProductA(Product): def operation(self): print("Performing operation A.") class ConcreteProductB(Product): def operation(self): print("Performing operation B.") class SimpleFactory: @staticmethod def create_product(product_type): if product_type == "A": return ConcreteProductA() elif product_type == "B": return ConcreteProductB() else: raise ValueError("Invalid product type.") # 使用简单工厂创建产品对象 factory = SimpleFactory() product_a = factory.create_product("A") product_a.operation() product_b = factory.create_product("B") product_b.operation() ``` 在上述示例中,`Product` 是一个抽象产品类,`ConcreteProductA` 和 `ConcreteProductB` 是具体产品类。`SimpleFactory` 是工厂类,通过 `create_product` 方法根据不同的产品类型创建相应的产品对象。 通过简单工厂模式,客户端无需知道具体的产品类,只需要通过工厂类来创建产品对象。这样可以降低客户端与具体产品类的耦合度,并且当需要新增产品时,只需要修改工厂类即可。 希望这个简单的示例能帮助你理解简单工厂模式在Python中的应用。如果有任何进一步的问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值