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

    文章

    9450

    浏览量

    156165
  • 封装
    +关注

    关注

    128

    文章

    9147

    浏览量

    147912

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    深度剖析Nios II 处理器的硬件抽象

    硬件抽象层(Hardware Abstraction Layer, HAL)是一个轻量级嵌入式运行时环境,它为用户应用程序和底层硬件提供了一个简单的设备驱动程序接口。HAL应用程序接口(API
    的头像 发表于 10-31 15:25 4650次阅读
    深度剖析Nios II 处理器的硬件<b class='flag-5'>抽象</b>层

    图文详情编辑接口的设计与实现

    。本文将从接口设计原则、核心功能、技术实现到代码示例,逐步解析如何构建一个健壮的图文详情编辑接口。我们将聚焦于RESTful API设计,确保接口安全、可扩展且高性能。 1.
    的头像 发表于 10-23 16:37 171次阅读
    图文详情编辑<b class='flag-5'>接口</b>的设计与<b class='flag-5'>实现</b>

    如何利用XPIO构建并实现带有Strobe的高速接口设计

    在 AMD Versal 自适应 SoC 器件中,SelectIO 是实现高速接口的重要组成部分。它为器件提供了灵活且高性能的通用 I/O 资源,支持多种工作模式,能够满足源同步接口、异步接口
    的头像 发表于 10-17 09:22 2160次阅读
    如何利用XPIO构建并<b class='flag-5'>实现</b>带有Strobe的高速<b class='flag-5'>接口</b>设计

    商品图片批量上传接口设计与实现

    ? 在电商平台或内容管理系统中,商品图片的高效管理是核心需求之一。批量上传接口允许用户一次性上传多张图片,显著提升操作效率。本文将逐步介绍如何设计并实现一个可靠的商品图片批量上传接口,涵盖接口
    的头像 发表于 10-13 15:25 220次阅读

    苏宁购 API 接口:苏宁购平台促销活动用户参与度分析

    ​ 在电商平台的激烈竞争中,促销活动是提升用户粘性和销售转化的核心策略。苏宁购作为中国领先的零售平台,其API接口为开发者提供了高效的数据访问能力,助力深度分析用户参与度。本文将逐步探讨如何利用苏
    的头像 发表于 09-01 17:15 498次阅读
    苏宁<b class='flag-5'>易</b>购 API <b class='flag-5'>接口</b>:苏宁<b class='flag-5'>易</b>购平台促销活动用户参与度分析

    利用苏宁购 API 接口实现苏宁购店铺线上线下库存一体化

    ​  在当今零售业中,线上线下库存一体化已成为提升运营效率的关键策略。苏宁购作为领先的电商平台,其开放的API接口为商家提供了实现这一目标的强大工具。本文将逐步解析如何通过苏宁购A
    的头像 发表于 09-01 16:57 609次阅读
    利用苏宁<b class='flag-5'>易</b>购 API <b class='flag-5'>接口</b>,<b class='flag-5'>实现</b>苏宁<b class='flag-5'>易</b>购店铺线上线下库存一体化

    揭秘苏宁购 API,让苏宁购店铺会员营销更精准

    ​ 在当今电商竞争激烈的环境中,苏宁购作为中国领先的零售平台,为店铺提供了强大的技术工具——API(应用程序接口),帮助商家实现会员营销的精准化。本文将从基础概念入手,逐步解析苏宁
    的头像 发表于 08-29 11:01 516次阅读
    揭秘苏宁<b class='flag-5'>易</b>购 API,让苏宁<b class='flag-5'>易</b>购店铺会员营销更精准

    苏宁购 API 接口:开启苏宁购全场景零售数据融合新时代

    Interface)作为系统间通信的桥梁,不仅实现了线上线下数据的无缝集成,还为企业、开发者和消费者提供了前所未有的数据驱动体验。本文将从 API 接口的核心价值、全场景零售的内涵,以及数据融合的技术实现三个方面,探讨苏宁
    的头像 发表于 08-29 10:47 461次阅读

    控智驾与普力达成战略合作

    近日,普力股份有限公司与控智驾科技股份有限公司在新疆国际煤炭工业博览会现场签订战略合作协议。
    的头像 发表于 07-21 09:28 691次阅读

    飞凌嵌入式ElfBoard ELF 1板卡-Regmap的优势

    接口的具体实现细节。这种抽象接口简化了驱动程序的开发和维护,提高了代码的可移植性和可重用性。 二、配置灵活:使用 Regmap,驱动程序需要
    发表于 05-22 10:39

    通携&lt;飞云&gt;系统助力物联网新变革!

    成本,拓展服务,增加价值,可以将各种物体通过信息传感器和网络技术相连的新型网络,实现对物体的智能化管理和控制。 二、飞云系统的主要应用场景 1、智能仓库管理: 通过蓝牙设备(Beacon)绑定物品,对仓库的库存状态可以在货物进出
    的头像 发表于 03-28 15:28 643次阅读
    飞<b class='flag-5'>易</b>通携&lt;飞<b class='flag-5'>易</b>云&gt;系统助力物联网新变革!

    华录智慧交管大模型实现交通数据价值的深度挖掘与应用

    华录将多年积累的数据治理经验与DeepSeek卓越的推理能力深度融合,实现了交通数据价值的深度挖掘与应用。“DeepSeek+小”智能引擎双驱动,让交通管控更智能、更高效,让每一位交警真切感
    的头像 发表于 03-08 13:48 1383次阅读

    系统建模与抽象层次:从模块到物理实现

    搭配定制软件。要让这些新产品成功上市,应采用怎样的最佳开发流程呢?硬件设计师正在借鉴软件开发团队的经验,在开发初期实施系统级设计。了解系统建模和抽象层次在硬件和软件
    的头像 发表于 03-07 18:01 552次阅读
    系统建模与<b class='flag-5'>抽象</b>层次:从模块到物理<b class='flag-5'>实现</b>

    LabVIEW抽象消息使用教程(上)

    自学LabVIEW的Actor FrameWork的消息与抽象消息的时候肯定会觉得非常模糊。小编将给大家带来一个有关抽象消息的教程,分为上下两期,本期将带领大家创建Actor中的方法并为方法创建对应的消息。
    的头像 发表于 01-03 14:22 2042次阅读
    LabVIEW<b class='flag-5'>抽象</b>消息使用教程(上)

    利用FPGA实现USB 2.0通信接口

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