代码阅读方法与实践(三)
我们分析的许多系统都遵循一种简单的“主程序和子例程”结构。常见的、重要的结构可以归类为少数迥然相异的构架类型:集中式储存库、数据流、面向对象或分层构架。这些构架类型常常结合成一个层次结构用来控制大型系统的复杂性。接下来我们将独立的分析每种构架类型,但是一个系统可以同时展示出多种不同的构架类型。以不同的方式检查同一个系统、分许系统的不同部分、或使用不同级别的分解,都有可能发现不同的架构类型。
集中式储存库的构架模型依赖于一个中心过程或数据结构,他在系统中担任控制或信息的集线器。即使不需要数据库提供的数据持久型,系统也常常使用集中式储存库。这种情况下,储存库一般作为大量不同代码元素的通信集线器。不相关的代码块能够通过访问储存库互相传递信息,无需付出努力对程序进行构造,使之适合于数据流。我们将这样的存储库称为黑板系统。当处理过程可以建模、设计和实现成一系列上午数据变换时,常常会使用数据流(或管道过滤器)构架。数据流构架的一个明显的征兆是:程序中使用的临时文件或流水线在不同进程间进行通信。画一个流程图可能会对了解整个系统的结构有所帮助。面向对象结构的系统,将他们的设计建立在维护自身状态并互相作用的对象上。我们分析的一些系统结构隐式的基于一种特殊控制模型:在数据流结构中,子系统受控于数对象的结构中,控制中,控制一般通过方法调用来协调。其他常见的、重要的控制模型有时间驱动型、基于系统管理器或围绕状态变迁。据的流动,而在面向自底向上的结构,和自顶向下的构架结构相似,都涉及到系统中单个元素的包装方式,在处理大量的代码时,了解将代码分解成单独单元的机制极为重要。识别出重用的构架元素后,可以查找其最初的描述,了解正确地使用这种架构的方式,以及可能出现的误用。
代码上可能执行的一些典型任务:识别出一个特定实体的声明,确定函数、变量、方法、模板或接口的类型;找到特定实体定义在什么地方;找出所有用到某个实体的位置;列出违背代码规范的代码;发现对理解给定代码段所有有所帮助的代码结构;查找解释特定的注释;检查常见的错误;查看代码的结构;了解代码如何与他所在的环境交互。
许多词汇工具的能力;与灵活性都来自于正则表达式的应用。正则表达式由一系列字符组成,我们通过将常规字符与元字符组合起来,创建正则表达式,指定一个能够精确匹配我们想要查找的代码项的处方。一些编译器(例如Emacs和vi),将正则表达式的查找与索引文件结合起来使用,可以高效的找出源代码中的各种定义。大项目一般拆分成多个文件,这些文件有时还会组织到一个目录结构中。Grep打印所有与给定模式匹配的行,用grep搜索代码。Diff程序能够比较两个不同文件或目录,列出要让文件一致必须加以修改的那些行为。
有时,很平常并且很明显能够自动执行的代码阅读任务,却找不出适用的工具来进行处理,
Unix外壳及工具,现代解释型编程语言,比如:perl、python和visual basic 都很适合创建定制的代码阅读工具。用编译器不仅仅能够完成源代码到目标代码的转换;还可以对程序进行不同级别的分析利用编译器获取程序信息的六种方式:生成警告消息;抓住生成错误信息的代码;生成程序清单;获取预处理输出;分析生成的符号(汇编)代码;完成最终的目标代码。代码浏览器可以帮助我们给你阅读大量的源代码,美化器可以修复那些在编写过程中确实没有一致地遵循任何格式规范的代码;采用那些无人维护的代码;创建代码的临时版本,协助对代码的解读;集成统一大项目中的代码。实际运行程序往往可以更深刻地理解程序的运作,尤其是文档缺乏或是已经过时的程序,这种情况下可以不去一行一行的理解程序的代码,而是用测试数据运行该程序,观察他的外部行为。还可以打印出来,可以试着向别人介绍你在阅读的代码。