首页 / 软件开发 / JAVA / 演化架构与紧急设计: 积累惯用模式
演化架构与紧急设计: 积累惯用模式2011-08-18 IBM Neal Ford简介: 本期将之前的 演化架构与紧急设计 文章中的紧急设计概念与一个案例研究相结合,展示如何 发现、积累和利用代码中意料之外的设计元素。一旦理解了如何识别设计元素,便可以使用该知识改进代 码的设计。紧急设计使您可以发现代码中意料之外但是已成为代码库重要部分的那些方面。在本系列第一期 “研究架构和设计” 中,我曾断言每个较大的项目都包括超出所有人意料的设计元 素。详细考虑一个问题时,常常会发现有些本以为困难的事情实际上却更容易,有些本以为容易的事情实 际上却更困难。随后的几期则演示了发现隐藏的有趣的设计元素的一些方法。在本文中,我将那些思想相 结合,并提供一个扩展后的案例研究,在该案例研究中,使用一些工具和方法来发现代码库中被忽视但是 同样重要的部分。在 “组合方法和 SLAP” 中,我介绍了惯用模式(idiomatic patterns) 的概念。与四人组撰写的 Design Patterns一书普及的常规设计模式(Design Patterns)相比,惯用模式并不适用于所有项目。但 是,它们是代码中普遍存在的、有代表性的常见设计惯例。惯用模式的范围很广,从纯技术模式(例如项 目处理事务的方式),到问题域模式(例如 “处理订单前总是检查客户的信用”),都可以是惯用模式 。发现这些模式是紧急设计的关键。Big Design Up Front 设计方法学的支持者在开始编写代码前,要花费大量的时间确定当前应用程序 的所有必需的设计元素。编制的文档中的大多数内容对于解决方案的总体设计仍是重要的。但是,在实现 软件的过程中,会不断遇见意外。实现的每个设计元素与其他设计元素相互联系,形成极端复杂的依赖和 关系网络。代码中有些方面本以为平常不过,但是一旦要实现系统中其他所有必需的部分时,复杂度又随 之放大。由于不能理解代码中不同设计元素之间复杂的相互作用,导致在估算完成解决方案所需的努力时 困难重重。在软件方面,估算仍是一种玄妙的 “黑色艺术”,因为对于如此复杂的耦合和交互网络,实 在是难以理解,因而也难以分析。依赖于紧急设计的敏捷方法学则尝试一种不同的方法。敏捷架构和设计在编写代码前也不会避开设计 ,但是它们的实际工作者已经知道,只有等到实现了重要的部分后,才能彻底地理解整个问题。紧急设计 中的开发技巧使您可以推迟做决定,直到掌握了更多的上下文。精益软件运动有一个很好的概念叫做 最 后可靠时刻(last responsible moment):不是将决定推迟到最后时刻,而是最后可靠时刻。越是往后 推迟设计决定,就能掌握越多的信息,从而可以做出更精妙、更符合实际的决定。积累惯用模式紧急设计要求在已有代码中发现设计元素。可以将那些元素看作有复用潜力的有效的抽象。积累那些 惯用模式的一种技巧是使用指标组合。为了演示这种技巧,我将(像之前几期那样)使用 Apache Struts 代码库。之所以使用 Struts,并不是因为我认为它存在缺陷(实际上恰恰相反),而是因为它比较出名 ,并且是开源的。我认为每个代码库都包括惯用模式,所以可以使用任何项目。使用指标在 “通过指标进行紧急设计” 中,我讨论了使用指标来发现不熟悉的代码库中有趣的部分,作为重 构的目标,以改进设计。我使用了两个指标:圈复杂度(cyclomatic complexity) 和 传入耦合 (afferent coupling)。圈复杂度是衡量一个方法相对于另一个方法的相对复杂度的指标。因此,该指 标只有与其他圈复杂度指标相比较才有用。但是,可以说,具有较低圈复杂度的方法通常更简单。而传入 耦合则表示其他类通过字段或参数引用当前类的次数。我使用 CJKM 指标工具收集 Struts 代码库上的这 些数字。