用 C 语言编写设计模式--策略模式

C语言实现设计模式的往期回顾:

    1. 用 C 语言实现简单工厂模式!

    2. 用 C 语言编写建造者模式!

    3. 用C语言实现原型模式!

    4. 用 C 语言实现一个静态代理模式 !

    5. C语言实现设计模式--装饰模式!

    6. 用C语言实现适配器模式!

    7. 用 C 语言编写设计模式--模板模式

    8. 用 C 语言实现有限状态机 FSM--基于表驱动

👀

   

一、概述

1.策略模式简介

策略模式 (Strategy)也叫是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。Strategy 模式主要用来平滑地处理算法的切换。

2.策略模式特点

准备一组算法,并将每一个算法封装起来,使得它们可以互换。

3.UML 类图

类图描述: 定义一个抽象接口类 Strategy,具体类 A、B、C 通过继承实现接口中的定义。Context 环境类,内部包含 Strategy 定义的对象,调用 Strategy 类的 operation(),通过多态的发生实现不同的操作。

👀

   

二、设计思路

本片以笔记本电脑实现联网功能为例,有 3 种联网方式,通过网线联网、WiFi 联网、USB 连接手机提供网络。为了举例,假设每一种联网方式对于笔记本电脑来说都是一种操作算法,我们把这三种算法抽象一个公共类 Strategy,如果 Computer(电脑)联网访问 Strategy 提高的统一抽象接口,通过发生“多态”实现不同的联网功能。

具体的策略设计模式的类图如下:

👀

   

三、实现

1.策略模式抽象接口结构体的定义

typedef struct Istrategy
{
    int (*operate)(void* obj);
    void (*free)(void* obj);
}Istrategy;

2.具体策略类实现, 使用网线连接网络结构体的实现​​​​​​​

typedef struct net_cable_strategy
{
    int (*operate)(void* obj); //“继承”抽象接口函数
    void (*free)(void* obj);  //“继承”抽象接口函数
    float rate; //自身特有属性
    float len;  //自身特有属性
}net_cable_strategy;
//使用网线联网函数实现
static int net_cable_operate(void *obj)
{
    if(!obj) return -1;
    net_cable_strategy* nobj = (net_cable_strategy*)obj;
    printf("使用【网线】给电脑连接网络...\n");
    printf("网络速率: %.2fM/s\n", nobj->rate);
    printf("网线长度: %.0fm\n", nobj->len);
}
//释放结构体内存
static void net_cable_free(void *obj)
{
    if(!obj) return;
    free(obj);
    obj = NULL;
}
//“构造函数” 创建一个对象
net_cable_strategy* construct_net_cable(void)
{
    net_cable_strategy* obj = (net_cable_strategy*)malloc(sizeof(net_cable_strategy));
    if(!obj) return NULL;
    obj->operate = net_cable_operate;
    obj->free = net_cable_free;
    obj->rate = 53.34;
    obj->len = 100;
    return obj;
}

3.具体实现类,通过连接 WIFI 提供网络​​​​​​​

typedef struct net_wifi_strategy
{
    int (*operate)(void* obj); //“继承”抽象接口函数
    void (*free)(void* obj); //“继承”抽象接口函数
    float rate;    //自身特有属性
    char *describe;//自身特有属性
}net_wifi_strategy;
//使用WIFI联网函数实现
static int net_wifi_operate(void *obj)
{
    if(!obj) return -1;
    net_wifi_strategy* nobj = (net_wifi_strategy*)obj;
    printf("使用【WIFI】给电脑连接网络...\n");
    printf("网络速率: %.2fM/s\n", nobj->rate);
    printf("描述:%s\n", nobj->describe);
}
//释放内存
static void net_wifi_free(void *obj)
{
    if(!obj) return;
    net_wifi_strategy* nobj = (net_wifi_strategy*)obj;
    if(nobj->describe) free(nobj->describe);
    nobj->describe = NULL;
    free(obj);
    obj = NULL;
}
//“构造函数” 创建一个对象
net_wifi_strategy* construct_net_wifi(void)
{
    net_wifi_strategy* obj = (net_wifi_strategy*)malloc(sizeof(net_wifi_strategy));
    if(!obj) return NULL;
    obj->operate = net_wifi_operate;
    obj->free = net_wifi_free;
    obj->rate = 23.34;
    obj->describe = (char*)malloc(64);
    sprintf(obj->describe, "WIFI4, 802.11n, 频段 2.4GHz, 理论最大速率 600Mbps");
    return obj;
}

4.使用 USB 连接手机通过网络定义与实现和上面的类似,限于篇幅,不再赘述。

👀

四、功能测试

下面是 main 函数,测试策略模式功能。通过“构造函数”创建对象的联网对象,实现不同的联网功能,而调用接口和流程保持不变。​​​​​​​

int main(void)
{   
    printf("Test Strategy Mode...\n");
    Istrategy *net = NULL;
    computer* com_obj = NULL;
    net = (Istrategy *)construct_net_cable();
    com_obj = construct_computer(net);
    com_obj->work(com_obj);
    com_obj->free(com_obj);
    printf("-----------split-----------\n\n");
    net = (Istrategy *)construct_net_wifi();
    com_obj = construct_computer(net);
    com_obj->work(com_obj);
    com_obj->free(com_obj);
    printf("-----------split-----------\n\n");
    net = (Istrategy *)construct_net_usb();
    com_obj = construct_computer(net);
    com_obj->work(com_obj);
    com_obj->free(com_obj);
    printf("-----------split-----------\n\n");
    return 0;
}

测试结果:

                                                                        👀

   

五、策略模式特点总结

策略模式的优点: 

A. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。 

B. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。 

C. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。 

D. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。 

E. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离

缺点: 

A. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。 B. 策略模式造成很多的策略类。

虽然C语言是面向过程的编程语言,但是我们在设计程序的时候,可以考虑用面向对象的方式去设计,这样提高我们程序的“高内聚、低耦合”特性,便于维护。

👀

   

六、总结

想要完整设计模式代码的小伙伴:在微信公众号【Linux编程用C】后台回复    designer   即可获取,不断更新中!


这个是交流群,欢迎大家扫描加入,一起分享学习!

(注:如果二维码过期了请添加小C微信号:LinuxCodeUseC 拉入群聊)

PS:若大家想看C语言版本的其他设计模式,

请大家 点赞! 转发!关注吧!~~

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值