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

    文章

    7639

    浏览量

    148494
  • 封装
    +关注

    关注

    123

    文章

    7278

    浏览量

    141096

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

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

收藏 人收藏

    评论

    相关推荐

    传感器抽象框架有哪些

    传感器抽象框架是一种用于开发和管理传感器网络的软件架构。它提供了一种抽象和整合的方式来处理传感器节点、传感器数据和传感器网络的通信。本文将详细介绍传感器抽象框架的背景、设计原则、实施方式以及应用领域
    的头像 发表于 12-28 14:08 235次阅读

    java抽象类可以有构造函数吗

    。在 Java 中,抽象类是一种不能直接实例化的类,它通常用作其他类的父类或接口实现类。抽象类可以包含抽象方法和非
    的头像 发表于 11-21 10:23 367次阅读

    java抽象类可以有普通方法吗

    Java中的抽象类可以有普通方法,但它也可以有抽象方法。抽象类是一种中间状态,介于普通类和接口之间。它允许定义方法的具体实现,同时也可以定义
    的头像 发表于 11-21 10:22 593次阅读

    如何理解java中的抽象

    Java中的抽象类是一种特殊的类,无法被实例化,只能被继承。它是一个中间层的类,位于具体类和接口之间,用于定义通用的属性和方法,并提供一些默认的实现抽象类经常被用来作为其他类的基类,
    的头像 发表于 11-21 10:16 276次阅读

    java接口是特殊的抽象类吗

    的区别。 首先,从语法和定义上来看,接口抽象类是不同的。接口是用interface关键字定义的,而抽象类是用abstract关键字定义的。根据Java语法,一个类只能继承自一个父类,
    的头像 发表于 11-21 10:07 268次阅读

    抽象类可以实现接口

    中,我将详细介绍抽象类和接口的概念,以及抽象类是否能够实现接口的问题。 首先,让我们先来了解一下抽象
    的头像 发表于 11-21 09:49 445次阅读

    Java中抽象类和接口的介绍

    Java是一种面向对象的编程语言,提供了抽象类和接口两种机制来帮助开发人员组织和管理代码。本文将详细介绍Java语言中抽象类和接口的概念、特点、使用方式以及它们之间的区别和联系。
    的头像 发表于 11-21 09:47 225次阅读

    java接口抽象类的区别

    接口抽象类的区别,包括定义、实现、字段、构造函数、继承、多态、默认方法等方面。 定义 接口表示一种契约,它只是一种规范或协议,定义了类应该包含哪些方法以及它们的签名,但没有提供方法的
    的头像 发表于 11-21 09:45 275次阅读

    TLM抽象模型介绍

    (1)OCP-IP TLM抽象模型 OCP-IP(Open Core Protocol International Partnership)是推动IP核接口标准化的国际组织。OCP-IP提出
    的头像 发表于 11-02 14:57 326次阅读
    TLM<b class='flag-5'>抽象</b>模型介绍

    AUTOSAR架构MCAL、服务层、ECU抽象层介绍

    1 微控制器抽象层(MCAL) AUTOSAR CP的微控制器抽象层(MCAL)是AUTOSAR软件架构中的一个重要组成部分,它提供了对底层硬件的抽象和访问接口,以
    的头像 发表于 10-27 15:36 3297次阅读

    经典C语言接口实现:创建可重用软件的技术

    C语言接口实现(创建可重用软件的技术)概念清晰、内容新颖、实例详尽,是一本有关设计、实现和有效使用C语言库函数,掌握创建可重用C语言软件模
    发表于 09-25 06:42

    重用的验证组件中构建测试平台的步骤

    writer ) 进行区分,前者负责测试平台的构建和配置,后者可能对测试平台的底层了解较少,但用它来创建测试用例。 基于验证组件创建测试平台的步骤是:  Review可重用的验证组件配置参数。  实例化和配置验证组件。  为接口验证组件创建可
    的头像 发表于 06-13 09:14 353次阅读
    可<b class='flag-5'>重用</b>的验证组件中构建测试平台的步骤

    参数化接口和可重用VIP:第一部分

    ,接收此接口的设计模块可以通过此接口参考访问信号。但是,接口的更高级别函数也可以提供更强类型的通信,以更好地表示设计意图。以下是系统Verilog
    的头像 发表于 05-29 10:30 353次阅读

    SystemVerilog测试套件加速IP到SoC的重用

    如果没有经过深思熟虑的验证环境,验证团队会浪费大量时间在 SoC 级别重新创建验证环境以实现芯片级验证,因为他们不考虑重用最初开发的环境来验证其块级 IP。即使跨相同的抽象级别,也无法重用
    的头像 发表于 05-29 10:13 364次阅读
    SystemVerilog测试套件加速IP到SoC的<b class='flag-5'>重用</b>

    如何使用参数化编写可重用的verilog代码

    我们将介绍如何使用verilog参数和generate语句来编写可重用的verilog 代码。 与大多数编程语言一样,我们应该尝试使尽可能多的代码可重用。这使我们能够减少未来项目的开发时间
    的头像 发表于 05-11 15:59 710次阅读