现在的位置: 首页 > 综合 > 正文

如何阅读他人代码(五)

2017年11月17日 ⁄ 综合 ⁄ 共 2972字 ⁄ 字号 评论关闭

原文为繁体中文,地址:http://www.ithome.com.tw/itadm/article.php?c=48168

下文为经过Google翻译过的简体中文版,有翻译不准确的地方,请参照原文一起阅读:


 

阅读他人的程序码( 5 ) -找到程序入口,再由上而下抽丝剥茧

根据需要决定展开的层数,或展开特定节点,并记录树状结构,然后适度忽略不需要了解的细节这是一个很重要的态度。因为你不会一次就需要所有的细节,阅读都是有目的的,每次的阅读也许都在探索程序中不同的区域。

 

探索系统架构的第一步,就是找到程序的入口点。找到入口点后,多半采取由上而下(自上而下)的方式,由最外层的结构,一层一层逐渐探索越来越多的细节。 
我们的开发团队曾针对AOLWinampiPod的插件进行阅读及探索,不仅找到入口点,也找出,并理解它最根本的基础架构。从这个入口点,可以往下再展开一层,分别找到三个重要的组成及其意义: 
     init ( ) :
初始化动作 
     ●quit ( ) :
终止化动作 
     ● PluginMessageProc ( ) :
以讯息的方式处理程序所必须处理的各种事件

展开的同时,随手记录树状结构 

当我们从一个入口点找到三个分支后,可以顺着每个分支再展开一层,所以分别继续阅读的init ,退出,以及PluginMessageProc的内容,并试着再展开一层。阅读的同时,你可以在文件中试着记录展开的树状结构。 
     ●init ( ) :初始化动作 
     ● itunesdb_init_cc ( ) :
建立存取iTunes的数据库的同步对象 
     ●初始化资料结构 
     
●初始化的GUI元素 
     ●载入设定 
     
●建立log档 
     ● autoDetectIpod ( ) :
侦测的iPod插入的执行绪 
     ●quit ( ) :
终止化动作 
     ● itunesdb_del_cc ( ) :
终止存取iTunes的数据库的同步对象 
     
●关闭log档 
     
●终止化GUI元素 
     ● PluginMessageProc ( ) :
以讯息的方式处理程序所必须面临的各种事件
     ●执行所连接的iPodMessageProc
) 

 

这部分必须要留意几个重点。首先,应该一边阅读,一边记录文件。因为人的记忆力通常有限,对于陌生的事物更是容易遗忘,因此边阅读边记录,是很好的辅助。 
再者,因为我们采取由上而下的方式,从一个点再分支出去成为多个点,因此,通常也会以树状的方式记录。除此之外,每次只试着往下探索一层。从的init )来看你便会明白。 以下试着摘要的init )的内容: 

 

因为我们只试着多探索一层,而目的是希望发掘出下一层的子动作。所以在的init )中看到像“ itunesdb_init_cc ; ”这样的函数调用动作时,我们知道它是在初始化( )之下的一个独立子动作,所以可以直接将它列入。但是当看到如下的程序行: 

我们并不会将它视为的init )下的一个独立的子动作。因为好几行程序,才构成一个具有独立抽象意义的子动作。例如以上这两行构成了一个独立的抽象意义,也就是初始化所需的资料结构。 

理论上,原来的程序撰写者,有可能撰写一个叫做init_data_structure )的函式,包含这两行程序码。这样做可读性更高,然而基于种种理由,原作者并没有这么做。身为阅读者,必须自行解读,将这几行合并成单一个子动作,并赋予它一个独立的意义 ─初始化资料结构。 

无法望文生义的函式,先试着预看一层 

对于某些不明作用的函式叫用,不是望其文便能生其义的。当我们看到“ itunesdb_init_cc 这个名称时,我们或许能从“ itunesdb_init ”的字眼意识到这个函式和iPod所采用的的iTunes数据库的初始化有关,但循环”却实在令人费解。为了理解这一层某个子动作的真实意义,有时免不了要往前多看一层。 

原来它是用来初始化同步化机制用的对象。作用在于这程序一定是用了某个内部的资料结构来储存的iTunes数据库,而这资料结构有可能被多执行绪存取,所以必须以同步对象(此处是视窗的临界区)加以保护。 

所以说,当我们试着以树状的方式,逐一展开每个动作的子动作时,有时必须多看一层,才能真正了解子动作的意义。因为有了这样的动作,我们可以在展开树状结构中,为itunesdb_init_cc )附上补充说明:建立存取iTunes的数据库的同步对象。这么一来,当我们在检视自己所写下的树状结构时,就能轻易一目了然的理解每个子动作的真正作用。 

根据需要了解的粒度,决定展开的层数 

我们究竟需要展开多少层呢?这个问题和阅读程序码时所需的“粒度(粒度) ”有关。如果我们只是需要概括性的了解,那么也许展开两层或三层,就能够对程序有基础的认识。倘若需要更深入的了解,就会需要展开更多的层次才行。 

有时候,你并不是一视同仁地针对每个动作,都展开到相同深度的层次。也许,你会基于特殊的需求,专门针对特定的动作展开至深层。例如,我们阅读AOLWinampiPod插件的程序目录,其实是想从中了解究竟应该如何存取的iPod上的iTunes的数据库,使我们能够将MP3播放歌曲或播放清单加至此数据库中,并于的iPod中播放。 

当我们层层探索与分解之后,找到了parseIpodDb ,从函式名称判断它是我们想要的。因为它代表的正是剖析iPod的数据库,正是我们此次阅读的重点,也就达成阅读这程序码的目的。 

我们强调一种不同的做法:在阅读程序码时,多半采取由上而下的方式,而本文建议了一种记录阅读的方式,就是试着记录探索追踪时层层展开的树状结构。你可以视自己需要,了解的深入程度,再决定要展开的层数。你更可以依据特殊的需要,只展开某个特定的节点,以探索特定的细目。 

适度地忽略不需要了解的细节,是一个很重要的态度,因为你不会一次就需要所有的细节,阅读都是有目的的。每次的阅读也许都在探索程序中不同的区域;而每次探索时,你都可以增补树状结构中的某个子结构。渐渐地,你就会对这个程序更加的了解。 

 

 

 

抱歉!评论已关闭.