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

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

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

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

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

/ 一、简介 /

1.代理模式,是构造型的设计模式之一,是一个使用率比较高的模式,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。

2.所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

3.代理模式也叫做委托模式,在日常的应用中,代理模式可以提供非常好的访问控制。

4.代理模式的优点: 职责清晰高扩展性

5.代理模式的类图如下,我们作为client使用时,直接访问interface这个抽象接口,真实的RealSubject与Proxy代理类继承该interface抽象接口,并实现接口定义函数。

/ 二、设计实现 /

1.设计思路,本设计以服装店卖衣服为例,通过服装店自己卖衣服和淘宝店代理卖衣服对比,感受一下代理模式优点。

2.设计的抽象接口如下。

//定义的代理模式抽象接口
typedef struct IProxy_t
{
    void (*sale)(void *obj);                         //卖衣服接口
    void (*discount)(void *obj, float discount_num); //打折接口
    void (*free)(void *obj);                         //最后释放内存
}IProxy_t;

3.服装店相关定义的实现

//服装店结构体
//注: 前面三个函数接口顺序与IProxy_t定义的要一致。
typedef struct ClotheStore_t
{
    void (*sale)(void *obj);                        //卖衣服函数
    void (*discount)(void *obj, float discount_num);//打折函数
    void (*free)(void *obj);                        //释放内存
    float price;                                    //服装价格
}ClotheStore_t;
/**
 * 简介:实现释放内存接口
 * 参数:传入当前的服装店结构体
 * 返回值:无
*/
static void clothe_store_free(void *obj)
{
    ClotheStore_t *csobj = (ClotheStore_t*)obj;
    if(csobj) free(csobj);
}
/**
 * 简介:实现卖衣服函数接口
 * 参数:传入当前的服装店结构体
 * 返回值:无
*/
static void clothe_store_sale(void *obj)
{
    ClotheStore_t *csobj = (ClotheStore_t*)obj;
    printf("服装店: 卖衣服! 价格是: %.2f元\n", ((ClotheStore_t*)obj)->price);
}
/**
 * 简介:实现打折计算函数接口
 * 参数:传入当前的服装店结构体、 打折值
 * 返回值:无
*/
static void clothe_store_discount(void *obj, float discount_num)
{
    printf("服装店: 现在做活动打 %.1f 折, 欢迎选购! \n", discount_num);
    ClotheStore_t *cs = (ClotheStore_t*)obj;
    cs->price *= discount_num/10.0;
}
/**
 * 简介:服装店结构体构造函数
 * 参数:无
 * 返回值:创建的服装店对象
*/
ClotheStore_t* constructor_clothe_store(void)
{
    ClotheStore_t* obj = (ClotheStore_t*)malloc(sizeof(ClotheStore_t)); //申请内存
    obj->price = 588;                       //数据成员赋值
    obj->discount = clothe_store_discount;  //函数指针赋值,便于后续调用,下同
    obj->sale = clothe_store_sale;
    obj->free = clothe_store_free;
    return obj;
}

4.淘宝代理接口定义及实现如下。

//定义淘宝代理结构体
//注:前3个函数指针与IProxy_t定义一致,方便后续发生“多态”作用
//即动态选择函数执行
typedef struct ProxyTaoBao_t
{
    void (*sale)(void *obj);    //淘宝卖衣服
    void (*discount)(void *obj, float discount_num);//打折
    void (*free)(void *obj);    //释放资源
    void (*before)(void *obj);  //售前
    void (*after)(void *obj);   //售后
    ClotheStore_t *csobj;       //给服装店做代理
}ProxyTaoBao_t;
/**
 * 简介: 实现淘宝代理卖衣服函数接口
 * 参数:传入当前调用的结构体
 * 返回值: 无
 * 其他: 代理服装店卖衣服,实际上真正卖衣服还是服务站
 * 不过由淘宝代理,增加一些售前、售后服务等
*/
static void taobao_sale(void *obj)
{
    ProxyTaoBao_t *tbobj = (ProxyTaoBao_t*)obj;
    tbobj->before(tbobj);           //做售前工作
    tbobj->discount(tbobj, 9.5);    //淘宝做活动打折9.5折
    tbobj->csobj->discount(tbobj->csobj, 9.8); //商家打折9.8折
    tbobj->csobj->sale(tbobj->csobj);          //实际卖衣服还是服装商家
    tbobj->after(tbobj);            //做售后工作
}
/**
 * 简介: 实现淘宝代理打折函数接口
 * 参数:传入当前调用的结构体、打折值
 * 返回值: 无
*/
static void taobao_discount(void *obj, float discount_num)
{
    ProxyTaoBao_t *tbobj = (ProxyTaoBao_t*)obj;
    tbobj->csobj->price *= discount_num/10.0;
    printf("淘宝做活动, 全场打 %.1f 折! 欢迎选购!!!\n", discount_num);
}
/**
 * 简介: 实现淘宝代理售前函数接口
 * 参数:传入当前调用的结构体
 * 返回值: 无
*/
static void taobao_before(void *obj)
{
    printf("淘宝售前: 亲!欢迎咨询...\n");
}
/**
 * 简介: 实现淘宝代理售后函数接口
 * 参数:传入当前调用的结构体
 * 返回值: 无
*/
static void taobao_after(void *obj)
{
    printf("淘宝售后: 亲!有问题请联系我哦...\n");
}
/**
 * 简介: 实现淘宝代理free函数接口
 * 参数:传入当前调用的结构体
 * 返回值: 无
*/
static void taobao_free(void *obj)
{
    ProxyTaoBao_t* tbobj = (ProxyTaoBao_t*)obj;
    if(tbobj->csobj) free(tbobj->csobj);
    if(tbobj) free(tbobj); //释放资源
}
/**
 * 简介: 淘宝代理构造函数,申请对象资源,初始化等
 * 参数:无
 * 返回值: 淘宝代理对象结构体指针
*/
ProxyTaoBao_t* constructor_proxy_taobao(void)
{
    ProxyTaoBao_t* obj = (ProxyTaoBao_t*)malloc(sizeof(ProxyTaoBao_t));//申请内存
    obj->after = taobao_after;              //赋值函数指针,便于后续指针调用
    obj->before = taobao_before;            //赋值函数指针,便于后续指针调用,下同
    obj->csobj = constructor_clothe_store(); //创建实体店对象
    obj->discount = taobao_discount;    
    obj->free = taobao_free;
    obj->sale = taobao_sale;
    return obj;
}

/ 三、测试 /

我们来测试对比一下服装店直接卖衣服和淘宝店代理卖衣服的区别,测试程序如下:

int main(void)
{
    IProxy_t *obj = NULL;
    printf("------------------------------\n");
    printf("普通实体店卖衣服:\n");
    ClotheStore_t *csobj = constructor_clothe_store();
    obj = (IProxy_t*)csobj;
    obj->discount(obj, 9.8);
    obj->sale(obj);
    obj->free(obj);
    printf("\n------------------------------\n");
    printf("淘宝代理卖衣服: \n");
    ProxyTaoBao_t *tbobj = constructor_proxy_taobao();
    obj = (IProxy_t*)tbobj;
    obj->sale(obj);
    obj->free(obj);
    return 0;
}

测试结果:

/ 四、总结 /

1.通过上面的测试结果,我们可以了解到,真正干活的还是服装店,不过加上代理模式后,整个销售流程更加完善,功能更加丰富。实际开放中,代理模式可以较小程度的修改原有程序来实现增加新的功能。

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

想要整个工程文件的小伙伴:在微信公众号【Linux编程用C】后台回复 【designer】 即可获取,不断更新中!

欢迎大家加小C微信【LinuxCodeUseC】,我们一起交流讨论学习!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值