zoukankan      html  css  js  c++  java
  • 设计模式的C语言应用-适配及系列模式-第六章

    模式介绍:适配系列模式

    在《设计模式》中提出的23种模式,其中适配器模式(Adapter),装饰者模式(Decorator),代理模式(Proxy)都属于原始功能到目标功能之间的桥梁。

    在面向对象里的设计里,这3种由于类的继承等面向对象特性,有比较明显的不同。在C语言里这些区别明显减弱,而且在实际的开发中,也没有这么多约束,所以统称为适配系列模式。

    以下引用设计模式的一些定义和说明。

    适配器模式Adapter

    将两个不同接口的类来进行通信,在不修改这两个类的前提下用中间件来完成这个衔接的过程。这个中间件就是适配器。所谓适配器模式就是将一个类的接口,转换成客户期望的另一个接口。

    装饰者模式Decorator

    如果通过继承和组合的方式来给一个对象添加行为,会造成关系复杂,过多的功能造成类爆炸。装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。

    代理模式Proxy

    代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的,同时也在一定程度上面减少了系统的耦合度。

    共同点和区别

     这3个模式听起来都很类似,都是在原对象上增加或者强化一些功能。

    按面向对象里的说法,代理模式和被代理的对象拥有完全相同的接口,不增加和强化功能。比如给一个取火车票的函数写一个代理函数,虽然接口一样,但是增加了取票人合法性,票的合理性等功能。把这个称为不增加和强化,我认为都是语义上的,而不是技术上的。

    而且由于与C语言不是类继承,接口是可以改的。比如取*** 函数增加一个时间入参功能,判断是不是合理的取票时间,如果根据接口改变就称这个不是代理模式了,那设计模式这个语义也没有什么意义了。从内核实现的观察者模式实现就知道,C语言里是灵活的,不因为改变了某些不影响架构的细节就换了一个模式。

    装饰模式不改变接口,但是会强化一些离原功能远一些的功能。但是同样由于C语言的灵活性,多远算远,怎么样才算强化都是难以量化的,就算改了一个入参强化,也不能说这个和装饰模式差别很大,况且由于C语言不存在类继承保持父类接口这回事,所以装饰模式也没有什么特殊的。

    适配器模式将两个不同接口的类来进行通信,也就是说,接口是不一致的,同上面的分析,在C语言里没有什么实质性区别,只不过对原接口改变多少的程度有差异而已。

    适配系列模式实现

     没什么特别的,在C里面,适配系列模式是一种隐性的模式,最常见的称呼是封装下接口,开发这就在不知不觉中使用了适配系列模式。下面举一个简单的例子。

    原函数样例

    也就是被适配和代理的函数

    int original_process(int a, int b)
    
    {
    
                  //do something
    
                  ret = //xxx
    
                  return ret;
    
    }

    传统适配模式函数样例

    可以看出传统适配模式将(int a, int b)接口适配成了(int c, int d, int e),并且返回值也做了适配。

    int adapt_process(int c, int d, int e)
    
    {
    
        int a, b;
    
        int ret;
    
                  //do something
    
        a = (c + d)%e; //some formula includes c,d,e or some other operation
    
        b = d + e;
    
       
    
                  ret = original_process(a, b) + 1;
    
       
    
                  //return something accroiding to ret
    
                  return ret;
    
    }

    传统装饰者模式函数样例

    传统意义上的装饰者模式不会改变接口,但是会增加功能。

    int decorator_process(int a, int b)
    
    {
    
        int a1, b1;
    
       
    
                  //do something optimization or other function
    
                 
    
        a1 = //do something with a or b
    
        b1 = //do something with a or b
    
       
    
                  ret = original_process(a1, b1)
    
                  //do something more, like optimize           
    
                  //return something accroiding to ret
    
    }

    传统代理模式函数样例

    传统代理模式既不能改变接口,也不能增加功能,通常只能做一些管控。

    int proxy_process(int a, int b)
    
    {
    
        int ret;
    
                  //check a, b
    
        if(a < 5)
    
        {printf("error:a should bot less than 5
    ");}
    
        if(b < 0)
    
        {printf("error:b should >= 0
    ");}
    
       
    
                  ret = original_process(a, b)
    
        return ret;   
    
    }

    C语言适配系列模式

    如上分析,C语言在实际开发中,没有这么多传统模式限制,可以混合所有适配类模式的功能。

    int c_adapt_process(char c, char d, char e)
    
    {
    
        int a, b;
    
        int ret;
    
                  //check c, d
    
        if(c < 5)
    
        {printf("error:c should bot less than 5
    ");}
    
        if(d < 0)
    
        {printf("error:d should >= 0
    ");}
    
        a = (c + d)%e; //some formula includes c,d,e or some others operation
    
        b = d + e;
    
       
    
        //do something optimization or other function
    
       
    
                  ret = original_process(a, b) + 1;
    
       
    
                  //return something accroiding to ret
    
                  return ret;
    
    }

    模式实现总结

    非常常用的设计模式,使用中都是自然而然的,没有想到其实也是几种退化的面向对象设计模式。

    来源:华为云社区  作者:lurayvis

  • 相关阅读:
    mode
    Jmeter获取不到cookie(备注:前面和后面的几个步骤都可以获取到cookie)
    [BAT]批处理脚本双击可运行,但在定时计划任务中无法执行(当前工作路径不对导致的)
    匹配数字、字母和?%&=-_这几个符号的正则表达式
    在jmeter的beanshell中用java获取系统当前时间
    Jmeter中正则表达式不区分大小写进行匹配
    通过BeanShell获取UUID并将参数传递给Jmeter
    JAVA Get UUID
    Jmeter报文体包含过大附件导致请求报文发送失败的解决办法
    [BAT]操作系统定时任务调用批处理忽略error继续运行的方法
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13165718.html
Copyright © 2011-2022 走看看