0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何更好实现和使用易重用抽象接口

AGk5_ZLG_zhiyua 来源:未知 作者:刘勇 2017-11-20 09:23 次阅读

>>>1.5.4实现接口

为了描述事物的完整性和相对封闭性,“封装”就提上了日程,细节从此不需要再去关注。而封装的传统定义是数据隐藏,如果还是这样看待封装,则具有很大的局限性。应该将封装视为任何形式的隐藏,即发现变化将其封装。封装不仅可以隐藏数据,而且可以隐藏实现和隐藏设计等所有的细节。

如果以更宽泛的方式看待封装,其优点是能够带来一种更好的分解程序的方法,于是封装层自然而然地就成为了设计需要遵循的接口。封装不会妨碍人们认识程序内部具体是如何实现的,只是为了防止用户写出依赖内部实现的代码。进而强迫用户在调用程序时,仅仅依赖于接口而不是内部实现,使抽象的概念接口和实现分离,将大大降低软件维护成本。

C语言中的*.c文件就是接口功能的具体实现,即用户不可见的内部实现,简称实现。一个接口可以有多个实现,它在发布后还可以改变、升级,因为它的改变不会对调用程序产生影响。大多数时候,*.c和*.h是成对出现的,一般来说,将某个子模块的声明放在*.h文件中,而将具体的实现放在对应的*.c文件中。*.c文件可以通过引用一个或多个*.h文件,达到共用各种声明的目的,但是*.h文件不可以引用*.c文件。

其实软件包就是一个用来描述定义一个库的软件,其中*.h文件作为库的接口,而实现这个库可能有一个或多个*.c文件,每个*.c文件包含1个或多个函数定义,软件包就是由*.h文件和*.c文件所组成的。这是一种良好的风格,适用于任何大型程序和小型程序。

假设开发一个由多个文件组成的大型程序pgm,这样就需要在每个*.c文件的顶部都放上这样一行:

#include "pgm.h" //用户自己编写的库文件

由此可见,通过共性分析使设计具有比较强的内聚,其价值就是实现紧凑的设计。从而使调用者无需关注实现的细节,实际上是函数的实现与使用它们的函数解耦了,swap()接口的实现程序清单 1.17。

程序清单1.17swap数据交换接口的实现(swap.c)

1 #include "swap.h"

2 void swap(int *p1, int *p2)

3 {

4 int temp;

5

6 temp = *p1; *p1 = *p2; *p2 = temp;

7 }

当p1和p2分别指向变量a和b时,则p1和p2存储的值就是&a和&b,即可用*p1和*p2表示a和b的值。如果写成以下这种形式:

temp = p1;

则交换的不是a的值,而是a的地址(p1的值就是a的地址)。而函数要交换的是a和b的值,不是它们的地址。因此需要使用*运算符和指针,该函数才能访问存储在这些位置的值并改变它们。即指针允许将局部变量的地址传给函数,然后在函数中修改局部变量。

由此可见,当将问题的“共性和可变性”分离开来,经过简化后发现,稳定不变的相同的处理部分(temp = *p1; *p1 = *p2; *p2 = temp;)都包含在抽象的模块中,可变性分析所发现的变化的变量a和b由外部传递进来的参数应对。从软件设计学角度来看,共性和可变性分析原理自然而然地成为了面向过程编程的理论基石。

注意,编写代码必须遵循结构化编程规则,即每个函数、函数中的每个代码块都应该只有一个入口、一个出口。实际上,只有在大函数中,这些规则才会有明显的好处。刚开始写代码时,都会冗长而复杂。有太多的缩进和嵌套循环,有过长的参数列表,甚至还会有重复的代码。需要不断打磨这些代码,分解函数、修改名称、消除重复,并保证测试通过。

有时我们并不关心指针所指向的变量的类型,此时可以使用并不指定具体数据类型的泛型指针void *。通常只允许相同类型的指针之间进行转换,但泛型指针能够转换为任何类型的指针,反之亦然。比如,C标准库中的memcpy()函数它将一段数据从内存中的一个地方复制到另一个地方。由于memcpy()可能用于复制任何类型的数据,因此将它的指针参数设定为void指针是非常合理的。比如,此前的swap()函数,可以将它的参数改为void指针,则swap()就变成了一个可以交换任何类型数据的通用交换函数,详见程序清单1.18。

程序清单1.18swap()函数(void_data_swap.c)

1 #include

2 #include

3

4 int swap(void *x, void *y, int size)

5 {

6 void *temp;

7

8 if((temp = malloc(size)) == NULL)

9 return -1;

10 memcpy(temp, x, size); memcpy(x, y, size); memcpy(y, temp, size);

11 free(temp);

12 return 0;

13 }

>>>1.5.5使用接口

只要传入待交换的变量的地址,即可确定如何通过接口调用它们,详见程序清单1.19。

程序清单1.19 swap数据交换函数范例程序

1 #include

2 #include "swap.h"

3

4 int main(int argc, char *argv[])

5 {

6 int a = 1, b = 2;

7

8 printf("%d, %d\n", a, b);

9 swap(&a, &b);

10 printf("%d, %d\n", a, b);

11 return 0;

12 }

由此可见,抽象的接口隐藏了它的内部细节,用户不再依赖具体的实现代码,而是依赖于抽象接口。抽象的接口几乎没有细节,没有什么需要变化的,使抽象和细节彼此隔离,因此抽象的接口非常容易被重用,其深刻地揭示了抽象的生命力。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8610

    浏览量

    151213
  • 封装
    +关注

    关注

    126

    文章

    7912

    浏览量

    142987

原文标题:周立功:实现和使用易重用的抽象接口

文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    利用FPGA实现USB 2.0通信接口

    USB 2.0接口实现方式 利用FPGA来实现USB 2.0接口的方式一般有两种,一是借助外围的USB接口芯片,二是FPGA内部
    的头像 发表于 12-30 13:59 140次阅读
    利用FPGA<b class='flag-5'>实现</b>USB 2.0通信<b class='flag-5'>接口</b>

    创新荣获2024全球电子成就奖年度微控制器/接口产品奖

    近日,在Aspencore 2024全球电子成就奖(WEAA)颁奖典礼中,旗下基于RISC-V内核的GD32VW553系列双模无线微控制器荣获“年度微控制器/接口产品”奖,这是兆创新连续第7年获得此项殊荣,充分展现了公司在产品创新和威廉希尔官方网站 研发领域的领先地位和卓越实力。
    的头像 发表于 11-06 11:52 302次阅读

    智能选择ADC/DAC可实现更好的软件定义无线电设计

    电子发烧友网站提供《智能选择ADC/DAC可实现更好的软件定义无线电设计.pdf》资料免费下载
    发表于 10-21 09:59 0次下载
    智能选择ADC/DAC可<b class='flag-5'>实现</b><b class='flag-5'>更好</b>的软件定义无线电设计

    使用ADC12_A实现热电偶接口

    电子发烧友网站提供《使用ADC12_A实现热电偶接口.pdf》资料免费下载
    发表于 10-18 10:13 0次下载
    使用ADC12_A<b class='flag-5'>实现</b>热电偶<b class='flag-5'>接口</b>

    单CPU 双项目开发实现更好的维护性和可行性应用说明

    电子发烧友网站提供《单CPU 双项目开发实现更好的维护性和可行性应用说明.pdf》资料免费下载
    发表于 09-12 09:42 0次下载
    单CPU 双项目开发<b class='flag-5'>实现</b><b class='flag-5'>更好</b>的维护性和可行性应用说明

    通无线DTU腾讯云通信实例

    通无线DTU腾讯云通信实例(基于MQTT)优——产品优,服务优,价格优——安装,使用,维护通——通讯威廉希尔官方网站 专家,精于通讯,万物互通
    的头像 发表于 08-30 11:45 357次阅读
    优<b class='flag-5'>易</b>通无线DTU腾讯云通信实例

    MSPM0-高级控制计时器有助于实现更好的控制和更好的数字输出

    电子发烧友网站提供《MSPM0-高级控制计时器有助于实现更好的控制和更好的数字输出.pdf》资料免费下载
    发表于 08-28 11:30 0次下载
    MSPM0-高级控制计时器有助于<b class='flag-5'>实现</b><b class='flag-5'>更好</b>的控制和<b class='flag-5'>更好</b>的数字输出

    克服设计难题-实现高性能接口

    电子发烧友网站提供《克服设计难题-实现高性能接口.pdf》资料免费下载
    发表于 08-28 09:41 0次下载
    克服设计难题-<b class='flag-5'>实现</b>高性能<b class='flag-5'>接口</b>

    串行外设接口的菊花链实现

    电子发烧友网站提供《串行外设接口的菊花链实现.pdf》资料免费下载
    发表于 08-27 09:45 1次下载
    串行外设<b class='flag-5'>接口</b>的菊花链<b class='flag-5'>实现</b>

    鸿蒙语言TypeScript学习第15天:【联合类型】

    接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体
    的头像 发表于 04-14 09:49 612次阅读
    鸿蒙语言TypeScript学习第15天:【联合类型】

    实践GoF的23种设计模式实现:桥接模式

    也即,将抽象部分和实现部分进行解耦,使得它们能够各自往独立的方向变化。
    的头像 发表于 04-14 09:30 454次阅读
    实践GoF的23种设计模式<b class='flag-5'>实现</b>:桥接模式

    AWTK 开源串口屏开发(14) - 界面重用

    把界面再拷贝一份。但是如果界面有多份,维护是一件麻烦的事情。今天我来介绍一下界面重用的问题。1.功能用同一个空调界面实现两台空调的设置。有两台空调客厅空调卧室空调
    的头像 发表于 03-23 08:23 366次阅读
    AWTK 开源串口屏开发(14) - 界面<b class='flag-5'>重用</b>

    TC1728没有LIN接口,只有UART接口,可以用UART接口实现LIN接口吗?

    TC1728没有LIN接口,只有UART接口。可以用UART接口实现LIN接口吗?
    发表于 02-06 06:51

    usb-c接口是什么意思 pd接口和usb接口哪个更好

    USB-C接口是一种连接标准,它提供了高速数据传输和充电功能,广泛应用于各种设备,包括电脑、手机、平板电脑、外接显示器和其他外围设备。PD接口(Power Delivery)是一种充电协议,它可
    的头像 发表于 01-31 17:01 8227次阅读

    FreeRTOS如何删除clib支持和抽象rtos?

    我目前在我的项目中使用FreeRTOS,但只使用了其最少的功能。 我需要删除 clib 支持和抽象 rtos,只保留 FreeRTOS。 这是为了实现更轻的应用程序并最大限度地减少依赖关系。 我怎么能那样做?
    发表于 01-25 06:19