长期以来,图片往往比文字更能帮助开发人员理解复杂的程序和审查代码,因此在软件开发中程序可视化的使用很普遍。UML 和其他主要图形形式的设计符号现在被广泛接受为沟通软件设计各个方面的最佳标准机制。一些基于模型的设计工具可以直接从图形表示中生成代码。在非正式的范围内,开发人员经常画出流程图或调用图来告知自己或其他人软件的重要方面。
UML 图都非常适合设计,但在开发过程的后期使用以帮助开发人员理解现有代码时存在两个重要缺点。首先,作为设计抽象,它们(正确地)省略了一些实现细节,但如果目标是理解完成的软件,这些细节通常很重要。其次,设计图在实现方面经常是陈旧的,导致对实际存在的系统的描述不准确或不完整。
非正式的可视化往往是短暂的,很少进入程序文档的正式记录。
很多时候,开发人员必须使用的唯一工件就是代码本身。不幸的是,代码可视化工具在历史上一直存在图表混乱和难以扩展到大型程序等问题。然而,正在出现的新工具正在开始解决这些问题。这些工具的主要优势是它们能够直接从代码本身生成有用的可视化。因此,它们保证是准确和最新的。
程序结构
程序由许多不同类型的组件之间的庞大而复杂的依赖网络组成。试图同时显示所有这些的可视化将太笨重而无用。事实上,没有单一的理想可视化。相反,对特定任务最有用的可视化是与执行该任务的工程师使用的心智模型相对应的可视化。一些更有用的程序结构如下:
类型层次结构
开发人员通常发现了解数据类型相互关联的各种方式非常有用。标准的 UML 类图以一种非常容易理解的形式表示类层次结构,其关联和包含关系处于比代码更高的抽象级别。虽然从设计的角度来看这很好,但程序员通常会发现查看类型之间的具体关系更有帮助。
包括树
C 和 C++ 程序通常会大量使用预处理器。如果做得好,这可以使程序易于理解,但通常它会插入一个阻碍理解的层。不规范地使用预处理器可能会导致依赖缠结,从而导致构建问题并损害可重用性潜力。因此,能够查看哪些文件包含在哪里可以帮助工程师解开复杂的依赖关系。
调用图
调用图,其中每个节点代表一个子程序,每条边表示对另一个子程序的一个或多个调用,通常被认为是最有助于可视化的程序结构。子程序是方便开发人员推理的单元,调用关系很好地捕获了数据和控制流。即使是一个小程序的调用图也可以有数百个节点和数千条边,因此人们早就认识到一次可视化整个调用图基本上是没有用的。相反,研究人员专注于将调用图可视化为更小、更容易消化的部分。
新的调用图技术和工具
由于调用图在程序理解中的重要性以及可视化它们所涉及的挑战,它们一直是许多研究的主题。特别是,已经开发出新技术来帮助控制调用图的复杂性。本节介绍了在提供高级可视化功能的静态分析工具中实现的一些机制。
自上而下的视图
调用图的自上而下视图有助于回答用户问题,例如“该程序的高级组件是什么,它们的属性和关系是什么?”
为了在程序理解的背景下解决这个问题,工具设计者从诸如谷歌地图之类的地理地图程序中汲取灵感。随着用户放大,更多细节开始显现:首先是城市,然后是城镇、村庄,最后是个别建筑物。显示的细节级别与缩放级别相关联。
程序由组件组成,这些组件本身又由较小的组件组成,依此类推,形成层次结构;虽然直接调用关系是在低级子程序之间,但它可以投射到包含这些子程序的高级组件。在调用图的自上而下视图中,最高级别的项目是目录。这些可以包含子目录和文件的某种组合,然后这些文件将包含子程序。因此,从一个框到另一个框的边仅表示包含在第一个框内的子程序调用了包含在第二个框内的子程序。
事实证明,这种方法在帮助开发人员更深入地了解程序方面非常有效。
在左侧窗口中,用户选择了从组件find到组件gnulib的边。此聚合边缘汇总的函数调用显示在右侧的窗格中。右侧窗口说明当用户放大查看单个功能时会显示更多细节。此缩放级别进一步说明了一个重要特性:开发人员能够将视图与代码本身相关联非常重要。因此,选择其中一个函数会导致显示该函数的源代码。
自下而上的视图
通常,开发人员会希望采用自下而上的方法。这有助于用户回答诸如“这个过程做什么,它如何适应程序的结构,以及它是如何被调用的?”之类的问题。
例如,假设某个程序在特定功能中崩溃。为了找到崩溃的原因并计划修复,开发人员可能会首先关注该单个函数,然后探索其附近的其他函数,以查看它调用和调用的其他函数。以前在白板上手动完成,一个工具可以自动处理绘图和布局的苦差事。
指标层
通过添加层来显示各种指标的价值,可以增加可视化的实用性。图 1 显示了一个示例。这显示了一个特别有用的可视化 - 树状图。在树状图中,节点的面积与度量标准成正比——通常是对项目大小进行编码的度量标准。然后将子节点平铺在顶级节点内。通常不显示边缘。在这个例子中,每个项目的颜色强度编码了静态分析工具发出的代码漏洞警告的数量。
图 1:中型程序(大约 200 KLOC)的树形图。颜色的强度表示在每个部件中检测到的静态分析警告的数量。
从这个角度来看,很容易挑选出风险最大的程序组件。树形图对于显示深度嵌套的结构非常有效,并且也非常适合前面讨论的缩放范例,其中更多细节在更高的放大倍率下显示。
当开发人员以交互方式使用它们来平移和放大和缩小,甚至添加和删除节点和边缘时,这些可视化是最有用的。如果没有足够的响应,与这样的界面交互可能会非常令人沮丧。显示数百个节点和数千条边可能是一个挑战。
审核编辑:郭婷
-
处理器
+关注
关注
68文章
19191浏览量
229314 -
C++
+关注
关注
22文章
2105浏览量
73531
发布评论请先 登录
相关推荐
评论