一线研发之声 https://bbs.21ic.com/?567930 [收藏] [复制] [RSS] ------最底层、最深邃、最负重的编程之歌

日志

一线研发之声 之 跑马灯变形记(四)

热度 9已有 4611 次阅读2014-11-8 06:43 |个人分类:一线研发之声|系统分类:嵌入式系统| 变形记, 跑马灯

跑马灯第三次变形:文件/模块划分

本系列入口:一线研发之声 之 跑马灯变形记(一)

不得不说,将每个功能抽象归类,放入不同的文件中进行编译链接,这是一个质的飞跃。但拆分模块将会极大地考验程序员的经验和思维习惯,它并不是单纯的把一个大文件拆分、编译通过就完事了,它体现的是一个工程师对于架构的理解深度。做得好,可以使系统模块间关系简单、层次分明。做得差,混乱之源就此埋下

在这次的变形中,我们将设备分为如下文件:



单纯的剪切、粘贴操作后,我们会发现两个编译问题:

(1)    main.c中,无法访问定时器的“flag_80ms全局变量”。

(2)    timer.c中,无法访问“宏定义常量LIGHT_INTERVAL_TIME”。

    对于许多人来说,第1个问题好解决,extern出来就是了。第2的问题就犯浑了,从应用角度讲,这个参数用来控制跑马灯闪烁的间隔时间,应该是跑马灯模块的。从技术实现角度讲,这个参数只有定时器会用到它,应该放在timer.c里面。怎么办呢?最后一个折衷的办法,就是把LIGHT_INTERVAL_TIME放到led_turning.h中,然后在timer.c中包含这个文档。

    在这样的惯性思路下,虽然仅有三个.c文件,但其.h文档的依赖关系已经开始令人难过了。于是许多人为了方便,会把所有的.h档通通放到main.h中,或者includes.h中。

    不管怎样,按照这个思路,最终我们或许得到了下面这个拆分方案。

上面这几个文件的依赖关系,我们可以整理成下面的依赖图,如下。

这样的实现细节,咋一看貌似也清晰明了,但实际上隐患暗藏。我们仔细分析一下所有文件之间的编译链接依赖关系,拨开迷雾,其实它们间真正的依赖关系是这样的,如下。

让我们以一种“局外人”的态度,来诘问自己几个问题,我们就知道何处别扭了。

(1)    为何timer模块的实现细节,却要取决于led模块如何定义呢?这样扯不清。

(2)    为何在“应用层”main.c文件中,为了使用led_turn模块,还需要把平台文件reg51.h包含进来呢?这如同强迫电视机的用户,去关心遥控器的实现原理一般,荒谬哦。

(3)    timer.c模块,把它内部的变量flag_80ms写权限也开发给main,这样妥当吗?这如同电器内部的高压线裸露在外,只要开了,就总有懵懂的孩童回去触碰,危险!!!

是的,分层思想,每个程序员都懂,在学校也都有好几个学期的专业课程来讲这个事儿。但到了具体的编码实现阶段,就错漏百出。初入泳池的旱鸭子,无论岸上如何背诵游泳精要,入水后一样苦苦挣扎而不得法。


一线研发之声 之 跑马灯变形记(五)


路过

鸡蛋
6

鲜花

握手

雷人

刚表态过的朋友 (6 人)

发表评论 评论 (3 个评论)

回复 wlzeagle 2014-11-10 13:30
这个写得不错
回复 ecoren 2014-11-12 17:17
再变一次,,
回复 pang576101312 2015-11-20 12:45
说的真心正确,感觉比起来自己的程序就像一坨翔