C 语言面向对象的封装方式
C 语言是面向过程的编程语言,一个程序的运行逻辑就是由一个个函数调用构成,函数里面会操作各种各样的数据结构。
因此,函数和数据结构,是 C 程序中的两大组成部分。
通常,我们接触的大多数 C 程序,代码的逻辑组织关系就如下图所示:
这种程序中,数据结构与函数是一种松耦合关系,数据结构的内部成员,对所有函数都是可见的,都是可读写的。一个函数会直接操纵多个数据结构,从而实现特定的业务逻辑。
这种设计的优点是:简单。数据结构和函数可以分开进行设计,适用于小型项目、快速构建原型。
但这种方式最大的问题是:当数据结构需要变化时,访问这个数据结构的大量函数都需要相应改动,工程量太大,在大型项目中几乎无法进行。需求变化时,会出现这类场景,在对历史代码进行重构时,也会出现这种场景。
因此,在大型项目中,更推荐的方式是封装。封装这个术语,常见于面向对象的编程语言中,其核心思想是将数据结构的内部构成、函数逻辑的实现对外界屏蔽,外界仅能通过其提供的接口函数来实现对数据结构的操纵、对特定逻辑的调用。
封装,即包括了对数据结构的封装,也包括了对函数逻辑的封装。
C 语言,尽管不是面向对象的编程语言,但依然可以实现优秀的封装能力。
采用封装的设计思想后,C 程序的代码逻辑组织关系就变成了:
上图中的红色框,就是封装。所有的数据结构,都被对应的函数封装起来了。外界无法直接访问这些数据结构的内部成员,只能通过暴露的接口函数来操纵这些数据结构。
所有的内部实现函数,也都对外界不可见,外界只能通过暴露的接口函数来调用相应的业务逻辑。
封装方式,对大型项目的演进是极度重要的!只要接口函数不变,那么每个子系统、每个模块内部的数据结构和内部实现,可以独立进行重构和演进,对别人没有任何影响!
而前一种方式下,一个数据结构变化了,几乎就是牵一发而动全身,别人都受影响,都得相应进行代码修改!
封装方式,对接口设计提出了更高的要求。如何切分程序的各部分职责,如何高内聚低耦合地设计接口函数,从接口函数名、参数和返回值中都屏蔽掉内部的具体实现,这些都需要高水准的设计。
一个大型项目的生命周期,会持续多年甚至数十年。良好的设计,会使得大型项目可以跟随业务需求而快速演进,最为关键的一点是每个子系统、每个模块可以独立进行演进,而无需各个团队之间任务的互相影响、前置任务等待等各种问题。能让各个团队能够充分并行工作,这对大型项目的进度和质量控制都是极度关键的。
下一篇文章,我会用一个例子,来展示 C 语言封装的具体做法。欢迎大家关注我。
版权声明: 本文为 InfoQ 作者【实力程序员】的原创文章。
原文链接:【http://xie.infoq.cn/article/c081b21cb417f61053e943dc0】。文章转载请联系作者。
评论