在敏捷软件开发中,您希望尽可能轻松地旅行,最简单的方法是选择最好的工件来记录信息。我使用术语“工件”来指代在软件开发项目中创建的任何模型、文档、源代码、计划等等。此外,您希望尽可能少地记录信息,最好只记录一次。例如,如果您在用例中描述业务规则,然后在业务规则规范中详细描述它,然后在代码中实现它,那么您需要维护相同业务规则的三个版本。最好只记录一次业务规则,最好是人类可读但可实现的代码,然后根据需要从任何其他工件引用它。
为什么要记录一个概念一次?三个原因:
- 减少维护负担。维护的表示越多,维护的负担就越大,因为您希望保持每个版本之间的同步。图1描述了传统软件开发构件的典型方法。每个工件中的字母表示其中存储的一条信息。例如,信息A(可能是我们上面提到的业务规则)在需求文档、测试模型和源代码中被捕获。
- 减少可跟踪性的负担。使用多个副本,您的可跟踪性需求就会更大,因为您需要将每个版本与其替代表示相关联,否则在发生更改时,您将永远无法保持它们的同步。是的,AM建议你只在感到疼痛的时候才更新,但是你拥有的副本越多,它越有可能在更早的时候开始疼痛。
- 增加的一致性。您拥有的副本越多,您拥有不一致信息的可能性就越大,因为您很可能无法保持版本的同步。
图1所示。传统的软件开发构件。
有趣的是,传统流程通常促进技术信息的记录,比如用三种不同的方式表示业务规则。与此同时,他们还将规定一些设计概念,如标准化和内聚,这将引导您开发一个只实现一次概念的设计。例如,数据规范化规则促使您将数据存储在一个地方,并且只存储在一个地方。类似地,在面向对象和基于组件的设计中,您希望构建只实现一个目标的内聚项(组件、类、方法等等)。如果这对于您的系统设计是可以的,那么对于您的软件开发构件也应该是可以的吗?我们显然需要重新考虑我们的方法。
视图,而不是复制
很明显,您应该将系统信息存储在一个地方,并且只存储在一个地方,最好是在最有效的地方。从软件开发的角度来看,这一概念被称为标准化,在编程界这是读写编程的一个重要方面,在技术文档界这被称为单一来源。单一来源的想法是只记录一次技术信息,然后根据需要从该信息生成各种文档视图。在上面的业务规则示例中,它将使用某种业务规则定义语言进行记录。一个人类可读的视图将为你生成需求文档(顺便说一下,这是说起来容易做起来难,但为了参数假设这是可能的)和一个实现视图生成将由您的业务规则引擎或编译应用程序源代码。
图2描述了一种策略,用于单次获取图1中包含的所有信息,然后通过使用生成器自动生成图1的原始构件。视图是根据需要从最新的源信息生成的,确保它们在生成时是最新的。
图2。单一来源信息的理想方法。
图2的一个重要含义是,尽管信息存储在一个地方,但是它可以以多种方式呈现给不同的受众。这称为引用文档本地化原则。例如,最终用户将需要以与程序员不同的格式查看信息。有些人喜欢看图表,而另一些人喜欢文本形式的信息。仅仅因为信息需要以多种方式查看和处理,并不意味着它需要存储多次。正如您从您的源代码库构建可工作的软件一样,您将从您的单源信息库“构建”您的文档视图。
图3描述了一种更加实际的方法。尽管您希望将信息存储在一个地方,而且只存储在一个地方,但事实是您的工具集可能不允许您这样做。此外,因为你只是人类,你会犯错误,并记录相同的信息两次。此外,图3还显示了软件开发中的一种常见情况:尽管许多文档可以用源代码表示,例如使用Java中的JavaDoc注释,但是一些关键信息仍然存储为外部文档。例如,敏捷人员通常拥有简洁的系统概述文档、发布说明和用户指南。
敏捷建模
图3。单一资源信息的现实方法。
传统单一的来源
要使传统的单一资源远景工作,您需要一种通用的方法来记录信息。达尔文信息类型化体系结构(DITA)是一种基于xml的格式,它被推广用于单源技术文档。没有什么可以阻止您创建自己的存储策略:通常采用自顶向下的方式处理单个源,文档的数据结构通常在项目的早期定义。传统单一来源的主要挑战是,它需要相当复杂的技术文档方法。这非常好,但是不幸的是,许多组织还不能实现这个愿景,并且发现他们需要远离这种方法。这并不意味着您需要把婴儿和洗澡水一起扔掉:您仍然应该努力使您所有的软件开发工件正常化。
敏捷的单一来源
您没有理由不采取一种更敏捷的方法,使您的系统构件的结构随着时间的推移而出现。这就是AM实践单源信息的来源。当您建模时,您应该总是问这样的问题:“我需要永久地保留这些信息吗?”,“如果是,那么存储这些信息的最佳位置在哪里?”以及“这些信息是否已经在其他地方捕获,我可以简单地引用它们?”有时候,存储信息的最佳位置是在敏捷文档中,通常是在源代码中。
有几个AM原则和实践支持敏捷的单一资源。它们是:
- 可执行的规范。这是最容易理解的单一来源信息的方法之一,通常也是最有成效的方法之一。通过在需求级别上采用测试驱动开发(TDD)方法,您的客户验收测试不仅是测试,而且是需求规范。类似地,在设计级别使用TDD,开发人员测试将构成详细设计规范的大部分。
- 应用正确的工件。应该使用最合适的工件捕获技术信息,包括手绘草图、详细的数据模型、用例规范或源代码。
- 有目的的建模。您应该知道为什么要创建一个工件,知道它是为谁创建的,以及他们将如何使用它。如果你不了解这三个因素,那么出于对某人、某个地方、某个时间可能需要它的恐惧,你很可能会记录下比你需要的更多的信息。这不仅会导致文档过多,而且很可能会无意中多次捕获相同的信息。
- 支持集体所有制。只有当每个人都可以访问一个共享的工件集合时,才有可能一次又一次地在正确的位置捕获信息。如果有些人没有完全的访问权限,那么他们就会有动力获取自己版本的信息。
- 建立泛化专家团队。当团队由只知道如何处理工件子集的专家组成时,您经常会在几个地方捕获相同的信息。例如,如果您的团队中有专家业务分析师、专家程序员和专家测试人员,那么这些团队中的每一个都将使用他们自己的方法来捕获业务规则——可能作为UML活动图、源代码和测试规范。当人们泛化具有一个或多个专长的专家,以及对完整软件生命周期的一般理解时,他们可以使用范围广泛的工件,从而减少了在多个地方捕获相同信息的需求。
- 模型与他人。有效的软件开发团队以合作和协作的方式一起工作。当人们单独工作时,他们将捕获他们自己的技术信息版本,这个版本可能与他们的同事维护的版本略有不同。通过与他人建模,您不仅可以一起开发模型或文档,还可以在整个团队中传播技能和知识,从而提高模型和文档保持一致和规范化的机会。
- 涉众的ROI最大化。开发团队中的每个人都应该确保涉众的钱被明智地使用。这不仅是一件好事,还增加了您的涉众将来希望继续与您合作的机会。多次捕获相同的信息、增加维护负担和增加可跟踪性需求真的有效吗?我不这么想。
其他支持单一来源的敏捷技术(至少在详细设计级别上)是代码重构和数据库重构。通过代码重构,您可以对源代码进行一些小的更改,以改进其设计;类似地,在进行数据库重构时,您可以对数据库模式进行一些小的更改,以改进其设计。许多重构,例如提取方法或引入查找表,分别显式地提高了系统底层对象或数据模式的规范化程度。
有趣的是,当一个敏捷团队由泛化的专家组成时,或者至少是由努力成为泛化专家的人组成时,当他们积极地尝试尽可能地做好工作时,存储信息的最佳位置往往是您的源代码。这正是许多极端程序员所声称的,尽管在我看来,他们一直在努力以传统IT专业人员能够接受的方式传达这一信息。许多传统主义者声称,如果您的文档在源代码中,那么它实际上就丢失了。他们真正想说的是,对于那些无法阅读源代码的人,或者至少对于那些没有工具(比如JavaDoc)的人来说,这些工具可以从源代码中提取关键信息,并以另一种格式显示出来,这些信息是丢失的。
正如找到一个完全规范化的关系数据库是极其罕见的一样,我怀疑您永远也不可能真正地完全单一地提供所有软件构件的源代码。在数据库性能方面的考虑,以及项目团队所犯的设计错误,都会导致模式不太正常。类似地,并非每个人都能够使用所有类型的工件——期望业务涉众能够阅读程序源代码是不现实的,支持这一愿景所需的超级工具将继续躲避我们(很可能永远如此)。
原文:http://agilemodeling.com/essays/singleSourceInformation.htm
讨论:请加入知识星球或者小红圈【首席架构师圈】
最新内容
- 3 days 13 hours ago
- 3 days 15 hours ago
- 3 days 15 hours ago
- 6 days 7 hours ago
- 6 days 14 hours ago
- 6 days 15 hours ago
- 6 days 15 hours ago
- 6 days 15 hours ago
- 1 week 4 days ago
- 1 week 4 days ago