《大话设计模式》笔记——策略模式

策略模式

"我"的理解

策略模式 是指同一个对象在不同情况下的策略行为有所差异,继续以之前的四则运算为例。

”加、减、乘、除“ 就是两个参数在不同情况下计算过程的差异性行为。所以在某种程度上,策略模式可能比简单工厂模式更适合 “计算器” 的实现。

UML图解

从下图可以看出,简单工厂模式 和 策略模式 的差异

  • 简单工厂:是通过创建不同的子类对象来解决不同的问题
  • 策略模式:创建本身对象,调用不同的行为接口从而实现解决不同的问题

在这里插入图片描述

代码实现

//~~~~ 计算器上下文类 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 计算策略函数 类型
typedef float (*TOptInterface)(float num1, float num2)

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

    // 创建上下文对象要实现的函数
    TOptInterface DoOperationInterface; 
} TCalcContext;

// 调用计算函数
float TCalcContextDoCalculate(TCalcContext* AObj)
{
    return AObj->DoOperationInterface(AObj->number1, AObj->number2);
}

// 创建计算上下文对象
TCalcContext* TCalcContextCreate(TOptInterface DoOperation)
{
    TCalcContext* result = NULL;
    
    // 在创建上下文对象的时候将实现的策略接口传入
    if (DoOperation != NULL)
        result = (TCalcContext*)malloc(sizeof(TCalcContext));       
    
    return result;
}

// 释放计算上下文对象
void TCalcContextFree(TCalcContext* AObj)
{
    if (AObj != NULL)
        free(AObj);
}

//~~~~~~~~~~~~~~~~~ 加法策略 ~~~~~~~~~~~~~~~~~~~~~~~~~

static float L_AddInterface(float num1, float num2)
{
    return num1 + num2;
}

//~~~~~~~~~~~~~~~~~ 减法策略 ~~~~~~~~~~~~~~~~~~~~~~~~~

static float L_SubInterface(float num1, float num2)
{
    return num1 - num2;
}

//~~~~~~~~~~~~~~~~~ 乘法策略 ~~~~~~~~~~~~~~~~~~~~~~~~~

static float L_MulInterface(float num1, float num2)
{
    return num1 * num2;
}

//~~~~~~~~~~~~~~~~~ 除法策略 ~~~~~~~~~~~~~~~~~~~~~~~~~

static float L_DivInterface(float num1, float num2)
{
    return num1 / num2;
}

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

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

int Test()
{
    // 选择计算方式
    TOperationType sign = InputOptType();
    // 创建计算上下文对象
    TCalcContext* ctx_obj = NULL;
    
    switch (type)
    {
    case kOptAdd : // 加法策略
        ctx_obj = TCalcContextCreate(L_AddInterface);
        break;
    
    case kOptSub : // 减法策略
        ctx_obj = TCalcContextCreate(L_SubInterface);
        break;
    
    case kOptMul : // 乘法策略
        ctx_obj = TCalcContextCreate(L_MulInterface);
        break;
    
    case kOptDiv : // 除法策略
        ctx_obj = TCalcContextCreate(L_DivInterface);
        break;  
        
    default :
        printf("暂不支持 %s 计算\n", GetOptTypeName(type));
    }
    
    if (ctx_obj != NULL)
    {   
        ctx_obj->number1 = InputFloat();  // 获取参数1
        ctx_obj->number2 = InputFloat();  // 获取参数2
        
        float ret = TCalcContextDoCalculate(ctx_obj)  // 得到计算结果
        printf("结果为:%f\n", ret);
        
        TCalcContextFree(ctx_obj);  // 释放对象
    }   
    
    return 0;
}

总结

Q: 为什么感觉 策略模式 和 简单工厂 差不多?

A: 就目前的四则运算的“计算器”代码来说,二者好像确实差不多,但是从用户代码(test())的结构上来看还是有细微差别。

  • 简单工厂:用户要认识两个层次,“工厂” 和 “产出对象” ,功能的实现是通过产生对象的动作来实现的,然而 “工厂” 更像一个制作 对象的流水线,不参与功能的实现。
  • 策略模式:这个流程中只有一个“对象”,这个对象在通过自己构造函数创建出来后,同样用来完成功能的实现。

此外,在用户使用上还有一点差异:决定对象功能函数接口的体现。简单工厂的对象接口在实现时的 选择(switch) 没有在用户层面体现,然而策略模式在对象接口的 选择 还是由用户决定。

虽然通过组合,可以让 策略模式 以 简单工厂 的形式体现在用户层面,但我目前认为这样做有点冗余。没有具体的适合的应用场景,强行结合只能让原本清楚的结构再次复杂,所以我的笔记只记录最基本的设计模式思路。

毕竟我不是经验老道的设计师,设计不出让人感觉清楚的组合模式。

(o゜▽゜)o☆[BINGO!]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值