极端设计






1.70/5 (20投票s)
2004 年 12 月 9 日
4分钟阅读

92166
测试应用程序设计
引言
我最近参加了一个关于设计和架构的会议。讨论的主题之一是如何不能在编码阶段严格地实现设计,那么花费太多精力在设计上是否真的值得。这让我陷入了沉思。我来自土木工程背景,在那里,如果没有周密的设计,一切都不会做得好,包括估算、合同条款和执行。
我的意思是,没有设计,你就无法建造一台新颖复杂的机器/桥梁/铁路系统。设计是将需求具体化的过程。真正的弱点在于我们没有提出清晰的设计,缺点通常在编码时才显现出来。 开发者必须仔细理解设计并编写代码。仅仅绘制一些UML图来笼统地解释问题是如何处理的,这是不够的。“一图胜千言”。但有人必须清楚地理解它,并写下这些文字来用脚本重现图像,甚至更多。
因此,我决定专注于如何最好地改进软件开发的设计阶段,而不是将其视为必要的邪恶。
背景
诚然,在许多项目中,到了编码阶段,通常与设计会有很大的差距。这主要是因为我们只关注提供高层设计,却从不关注开发人员需要什么来实现预期的输出。为了解决这个问题,我们需要在设计中增加更多的细节,而不是减少。细节(可以问问建筑设计师这意味着什么)应该被细化。
为了实现一个令人满意的设计,真正需要的是找到一种方法来测试设计,并证明它实现了应用程序的要求和编码要求。毕竟,我们测试代码,为什么不测试设计呢?也许低级设计可以与测试用例进行比较。
扩展设计
为了确保更完整的设计,请尝试按照适当的顺序执行以下操作:
- 加入伪代码。
通过这样做,设计师实际上是在尝试实现设计。在这个过程中,可以认识到设计中从编码角度来看的不足之处。甚至像类字段、属性、常量、枚举、用于执行特定任务的辅助/私有函数等编程细节,都可以在编写伪代码时识别出来。事实上,在编码阶段,开发人员将主要编写特定于语言的代码来实现伪代码。
这意味着我们现在有了一个两阶段的设计过程。首先,进行高层设计来实现通用架构。因此,设计模式、识别领域实体、领域实体之间的关系以及所有常规的设计工作都首先完成。然后,有经验的开发人员将通过尝试为设计实现伪代码来进一步推进。这可以被视为一种单元测试。
- 创建可追溯性矩阵
将每个需求/特定规则映射到我们的设计类/方法。这将有助于确保大多数问题已在设计中得到考虑。它还将帮助识别遗漏的内容。创建流程图并将图中的每个节点映射到你的设计元素。同样,这也可以是一个两阶段的过程。首先,创建与业务相关的高层流程图,并将其映射到高层设计(抽象类或接口)。然后创建低层流程图,并将其映射到具体的类/方法。这可以被视为一种集成测试。
- 文档。
是的,这是一个繁琐的过程,但它确实消除了编写代码时的许多困惑。因此,解释每个类、变量、属性、方法和事件的存在/用法,以便编码人员确切地知道如何处理它们。这样,即使是项目新手开发者也能够快速上手,而无需详细了解业务流程和项目特定的细微差别。
- 白盒测试
向项目中的同事和开发人员解释这些类如何支持工作流/流程。通过这种方式,设计师可以更好地理解开发人员的期望。
- 黑盒测试
让那些对项目了解不多的人阅读你的设计,解释他们从中理解了什么以及他们将如何实现它。
- 最后但同样重要的是,确保代码中不包含任何在设计中未体现的重要内容。
设计文档应成为编码的唯一参考。即使是使用项目中其他编码组件、DLL,也必须通过引用特定的设计文档在设计中提及。
底线
当然,要确保代码按预期工作,只能在测试阶段证明。测试驱动开发过程将确保你的输出是正确的(它不确保你以正确的方式开发)。进一步来说,如果测试驱动代码是最佳的做事方式,那么为什么不能有代码驱动设计、设计驱动需求和需求驱动客户呢?
需求和设计的变更随时都会发生,并且必须被接受(在一定范围内)。使用UML来解释设计并加入伪代码。而结对设计比结对编程更有价值。
发送邮件给我。