AnitiPatterns -- Lava Flow

来源:互联网 发布:linux入门书籍 编辑:程序博客网 时间:2024/05/14 23:03

-----------------------------------------------------------------------------

反模式名称:Lava Flow

别名:Dead Code(死代码)

最常见规模:应用层

重构方案名称:Architectural Configuration Management(架构配置管理)

重构方案类型:过程

根源:贪婪、懒惰

不平衡的力量:功能管理、性能管理、复杂性管理

-----------------------------------------------------------------------------

特征

刚出现时具有可变的本质,而一旦固化了就像玄武岩一样坚硬而难以去除。不可移动、逐渐失去作用。

“架构是关于如何浪费空间的艺术。”

——Phillip Johnson(美国著名建筑师)

该反模式在概念验证或原型代码迅速发展成产品的创新设计工场中令人难以置信地常见。它是一个不好的设计,以下是几个关键原因:

  ● 对Lava Flow进行分析、检验和测试的成本很高昂。所有这些工作都是没有价值的,完全就是浪费。实际上,几乎不可能进行检验和测试。

  ● 读取Lava Flow代码到内存中的代价也很高,会浪费重要的资源,影响性能。

  ● 和许多反模式一样,你会失去面向对象设计的内在优势。在这种情况下,你失去了在不扩散Lava Flow块的情况下进行模块化和复用的能力。

症状和后果

  ● 系统中频繁出现无法解释其合理性的变量和代码碎片。

  ● 没有文档的、似乎重要的复杂函数、类或代码段,它们与系统架构之间没有清晰的关系。

  ● 非常松散的、“进化中的”系统架构。

  ● 整段注释掉代码而没有解释或文档。

  ● 大量“正在变化”或“待替换”的代码区。

  ● 未使用的(死)代码,简单地留在那里。

  ● 头文件中存在未使用的、无法说明的或过时的接口。

  ● 如果移除了现有的Lava Flow代码,由于代码在其他地方被复用,它仍然可能会扩散。

  ● 如果没有对导致Lava Flow的过程进行检查,而后续开发人员在分析原始流时太匆忙或太不情愿,结果在试图绕过原始流时继续产生新的流,可能会导致产生指数形式的增长。这会让问题更复杂。

  ● 随着流的复杂化和硬化,很快就会无法为代码编写文档,也无法充分理解它的架构以便加以改进。

典型原因

  ● 在未考虑配置管理的情况下把研发代码放入到产品中。

  ● 对未完成的代码进行未受控制的分发。为实现某种功能而实现多种试验方法。

  ● 单个开发人员(也称为独狼,lone wolf)编写代码。

  ● 缺乏配置管理或没有充分遵循过程管理策略。

  ● 缺乏架构或者采用非架构驱动的开发。这一点对临时性很高的开发团队来说尤其普遍。

  ● 反复性的开发过程。软件项目的目标常常是不清楚的,或者反复发生变化。要解决变化,项目必须返工、倒退和开发原型。为了应对演示的最终期限,常见的做法是用很少的时间地对代码做出匆忙的改变来解决眼前的问题。永远都不会清理代码,让对架构的考虑和文档化工作被无限期地推迟。

  ● 架构疤痕。有时,会在进行了一些开发后发现在需求分析时做出的架构承诺是不可行的。系统架构可能需要重新配置,但很少会去掉那些内联的错误。注释掉不需要的代码甚至都有可能是不可行的,尤其是在现代开发环境中,可能有数百个文件包含系统的代码。“谁会看所有这些文件?把它们链接进来就是了!”

 已知例外

研发环境中的小规模、用后抛弃的原型非常适合使用Lava Flow反模式。在这种环境中,迅速开发是很重要的,其结果并不要求是可维持的。

 重构方案

只有一种可靠的方法来防止Lava Flow反模式:保证在产品代码开发前建立健全的架构。该架构必须受到配置管理过程的支撑,这个管理过程要保证开发符合架构规定,而且可以容纳“任务蔓延”(变化的需求)。如果一开始进行架构考虑时采取欺骗的态度,最终会开发不属于目标架构的代码,从而产生冗余的代码或死代码。经过一段时间,死代码就会成为分析、测试和修改时的问题。

在出现了Lava Flow的地方,治疗过程会非常痛苦。重要的原则是在活跃的开发中避免架构变化。这一原则尤其适用于计算体系,也就是定义系统集成方案的软件接口。项目管理过程必须把开发推迟到定义了清晰的架构并让开发人员都了解它之后。定义架构可能需要进行数个系统发现活动。要通过系统发现来找到那些实际使用的、对系统而言不可缺少的构件。系统发现还会确定那些可以被安全删除的代码行。这项活动相当冗长,它可能会需要一个有经验的软件侦探的调查技能。

在消除可疑的死代码时,有可能会产生错误。发生这种事的时候,要避免在充分了解出错原因之前马上修正出现的症状的冲动。要研究问题的依赖关系,这可以帮助你更好地定义目标架构。

要避免Lava Flow,重要的是建立系统层次的软件接口。它应该是稳定的、定义良好的,而且具有清楚的文档。从长远的角度看,与费力地排除坚硬的Lava Flow代码块相比,在软件接口质量上进行先期投入的成本可能要低很多倍。

类似于源代码控制系统的根据可以帮助进行配置管理。大多数Unix环境都捆绑了源代码管理系统,提供了基本的能力来记录受配置控制的文件的更新历史。