模式介绍:适配系列模式

在《设计模式》中提出的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\n");}

    if(b < 0)

    {printf("error:b should >= 0\n");}

   

              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\n");}

    if(d < 0)

    {printf("error:d should >= 0\n");}

    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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐