随着更具表现力的编程语言的发展,对软件设计规范的需求是否大大减少了?


16

对于许多IT人员(包括几年前的我自己),理想的软件开发过程是在编写一行代码之前,先创建带有许多UML图的详细设计文档。(这看起来像是瀑布模型的描述,但与敏捷相同,只是迭代次数较小。)

在过去的两三年中,我完全改变了主意。我仍然认为,带有相关测试用例的详细需求规范绝对是必不可少的。对于大型项目,在开始编写代码之前,我还需要概述总体体系结构。但是所有其余的都应该尽可能地用代码完成。在理想情况下,除了代码本身外,不应该对软件设计进行任何描述。

我是如何得出这个结论的?以下是一些参数:

反馈

用于编写文档或创建图表的工具几乎没有反馈。是的,有些建模工具可以对UML图进行一些一致性检查,但是它们是有限的,并且会产生大量开销。

没有反馈,很难识别和修复错误。

编写代码后,您将获得大量反馈,例如:

  • 来自编译器的错误和警告
  • 静态代码分析结果
  • 单元测试

错误可以快速识别并解决。

一致性

为了确保代码与您的文档一致,您必须一次又一次地检查。如果经常进行更改,则很难使代码和文档保持同步。

重构

有许多强大的工具和技术可用于重构代码,而重构文本描述或图表通常很困难且容易出错。


进行这项工作有一个先决条件:代码必须足够容易阅读和理解。这可能无法用Assembler,Basic或Fortran来实现,但是现代语言(和库)更具表现力。

因此,如果我的论点是正确的,则应该有一个趋势,即越来越少的轻量级软件设计规范和文档。这种趋势是否有任何经验证据?


2
由于敏捷开发随着行业的成熟而越来越受欢迎,因此前期设计不受欢迎。语言的表现力越来越强,工具的重量越来越轻,这使得更容易快速进行原型开发,从而实现了更加敏捷的开发。我认为两者之间存在某种因果关系。
恢复莫妮卡

14
以我的经验,“在编写一行代码之前用大量的UML图创建详细的设计文档”从来都不是一个好主意-至少在我从事专业程序员工作的那段时间里不是这样。比UML存在十年。但是,在期望系统具有特定大小时,在编码之前进行高层设计是一个好主意。但是,UML不是IMHO的正确工具。
布朗

2
懒得一个正确的答案:更富表现力的编程语言和更强大的计算机导致对功能越来越强大和复杂的程序的需求,这又导致了更复杂的需求规范。
whatsisname

2
推荐读物:击败平均值
罗伯特·哈维

1
我已经完成了具有完整UML设计的项目。我们从中生成代码。我得出的结论是,我再也不想这样做了。这是一个很多难以改变UML,这是修改代码; 大型UML模型至少与许多源代码一样笨拙。“生成的”代码很难阅读,生成器在代码中留下了“标记”。
尼克·基利

Answers:


9

我质疑语言越来越具有表现力的前提。使用c#中的当今ASP.NET代码,我所写的水平与使用Visual Basic编写ASP代码时的水平大致相同。我们仍然使用c ++。Javascript增加了功能,但总体而言语言没有改变。与SQL相同。

我认为这些其他更改更为重要:

  1. 采用自动化单元测试。有人会说测试规范。因此,我们没有删除编写规范的需求;而是用代码而不是Word文档编写它们。

  2. 部署方法的变化。过去,犯错是非常昂贵的,因为您将需要交付软件的更新副本。因此,您必须小心。使用网络驱动的应用程序,您可以部署修补程序以立即使用,并且可以承受对问题的反应而不是预期它们,从而可以随时进行代码重组。

  3. 采用设计模式。当每个人都知道这些模式时,您几乎不必设计任何东西。您可以说“添加存储库工厂”,而您的团队应该这样做,而无需查看UML。

  4. SOA的数据合同。如今,几乎所有东西都是SOA。您只需要一个WSDL。定义和记录数据传输格式的日子已经一去不复返了。当前向更多RESTful和微服务的转变继续了这一趋势。

  5. 软件较小。部分是由于SOA体系结构的结果,团队正在编写捆绑在一起的较小的程序。每个单独的组件都不太复杂,需要的前期设计也较少;同样,由于组件之间的接口定义会引起火灾,因此更容易更改体系结构的一部分而不会破坏整体解决方案。

  6. 大量使用已建立的库。.NET CLR提供了许多现成的功能,因此无需设计用于缓存会话数据的方案。诸如jQuery UI或Bootstrap之类的第三方库为编写代码以某种方式工作建立了标准。您不需要记录这些;团队应该能够使用它们。

  7. 行业成熟度。SWE已经了解到,没有“ Battlestar Galactica”项目需要您花费数年时间来努力实现特定目标。到那些年过去的时候,目标将会改变。今天,我们知道上市时间比在设计中完全按照我们想要的方式获得所有产品更为重要。

  8. 受过更好和更一致教育的工程师。如今,您可以聘请了解(最好)了解最佳实践的工程师,而他们只会在没有设计文档告诉他们怎么做的情况下实施这些最佳实践。

  9. TFS之类的生产力工具使您可以编写一个简单的任务,该任务引用一个用例,并为任何模棱两可的技术决策提供几个要点。您所需要的不只是这些。开发人员可以通过该工具审查,估算,获取代码审查,签入等内容。这比处理外部文档要有效得多,因为它将所有内容联系在一起。

您仍然需要某些方面的设计文档……例如,如果您的应用程序分为不同团队开发的不同组件,则至少需要告诉他们哪个组件负责哪些需求。但是在大多数情况下,当今的开发方法在为您提供工具的同时提供了更大的自由度,使您可以管理和控制开发者做出错误决定可能带来的风险。


3
我们的行业已经成熟了。项目5是迄今为止最重要的更改;它对所有其他方面产生积极影响。但是事实是,我们每5年对所有技术进行一次更改,这表明我们还有很长的路要走,而且语言表达能力(随着时间的流逝而相对稳定,因为在这一领域进行有意义的改进非常困难,这是一件事)比您认为的要多的收益。
罗伯特·哈维

1
这还不是全部进展:向前迈出的主要步伐是编译器的发明。但是我们仍然教流程图,汇编代码的抽象(以及许多其他过时的实践)。可能是因为我们忘记了为什么?
ctrl-alt-delor

6

我主张

出于简单的原因

对于许多IT人员(包括几年前的我自己),理想的软件开发过程是在编写一行代码之前,先创建带有许多UML图的详细设计文档。

自从1990年代以来就存在极限编程,从来没有认为它是“理想的” 。正如你所说:

在理想情况下,除了代码本身外,不应对软件设计进行任何描述。

被争论了很久以前。例如1992年的这篇传奇文章:什么是软件设计

上面的内容表明,您可以具有高度进化的体系结构和迭代方法的“极端”过程,而无需复杂的语言或IDE。

相反,我要说的是,这种“似乎”的转变是从具有大量图表和用例文档的前期设计过渡到更具进化性和迭代性的方法,只是“老派”管理人员被新的管理人员所替代,而新的管理人员则在新的管理人员中成长了。动态环境,对于谁来说更容易在更“敏捷”的环境中工作。


6

我几乎同意这一点,但我认为它比您暗示的要早得多。我还认为除了表达能力之外,还有另一个重要因素。当我父亲第一次开始编程时,他不得不创建打孔卡,并在计算机上安排时间。您每天可能有一次运行程序的机会。没有太多时间浪费在构建代码上,让它失败然后修复。您可能会得到2或3张照片,如果它不起作用,那么您就有麻烦了。

这样做的风险意味着,花费大量额外的时间来计划程序至关重要。人们会用铅笔将他们的代码写出来,然后将其转移到打孔的卡上。随着技术的进步,您可以直接在终端中进行编码,但是您仍在使用共享资源,而CPU则很昂贵。在这个世界上,测试优先的方法是完全站不住脚的。如果您不提前计划,您的同事将坐在干草堆旁。

计算资源以惊人的速度变得越来越便宜和更好。开发所有这些实践所依据的许多约束已完全消除。正如Euphoric指出的那样,这种转变的真正开始是在90年代。大部分前期设计的延续都是纯粹的惯性。

因此,是的,因为这样一个简单的事实,即编程语言更易于使用,因为将表达代码作为其自己的文档使用起来更为容易,因此对此产生了影响。产生一个可以告诉您代码说明内容的文档的成本很高,而且很有价值(在某种程度上不可避免地是错误的。)同时,将垃圾扔在墙上,看看有什么东西的成本基本上可以忽略不计。


3

我想您忘记了最初拥有设计文档的目的!

设计文档(需求,用例,模型等)使我们可以从高层次描述,理解和讨论系统。这些文档中遗漏的大量细节使它们变得有用。

有没有必要有其描述系统系统的确切行为文件的所有细节,因为的确源代码本身服务于这一目的。

可以将软件开发视为将高级人类可读规范转换为可由机器执行的低级明确规范的过程。但是,此过程需要一些输入


当然,绝对需要没有细节的高级文档。但这正是我对良好编程语言的期望。它应该允许以不同的细节级别编写代码。代码不必一定是底层指令的非结构化混乱。
弗兰克·普弗

@FrankPuffer图表的价值为100,000 LoC。
RubberDuck

1
@RubberDuck在我看来,从代码生成各种有用图表的能力(或缺乏这种能力)可以衡量一种语言的表达能力。没有可以用某种语言表达的图表。问题是该语言是否可以以易于书写或阅读的方式传达相同的信息。
JimmyJames

1
@RubberDuck:在某些情况下,图表确实有意义,例如,说明整体架构。但是我不认为它们应该是默认值。肯定有好的和有用的图,但是不幸的是,我所看到的大多数UML都比帮助更令人困惑。更糟糕的是,它通常与实际实现有所不同。
Frank Puffer

我喜欢您提到生成图@JimmyJames。与手动创建相比,我更喜欢生成。您的观点很正确,但是我想知道这是表达力还是工具的作用。
RubberDuck

1

在理想情况下,除了代码本身外,不应对软件设计进行任何描述。

这比您暗示的要远。甚至像依赖类型之类的东西(据我所知,从理论上讲也是很有前途的)已经有好几年了。

形式验证非常困难,因此,唯一使用形式验证的地方就是密码库。

单元测试

如果性能测试尚未成为主流,那么我认为这在很长一段时间内都不可行。

此外,编写好的测试(不必在每次重构时都进行编辑,但仍会捕获足够的错误)非常困难。

为了确保代码与您的文档一致,您必须一次又一次地检查。如果经常进行更改,则很难使代码和文档保持同步。

目前可能更容易使用文档测试工具。

进行这项工作有一个先决条件:代码必须足够容易阅读和理解。

不幸的是,很难设计出不仅极富表现力而且极具可读性的语言。诸如Go之类的语言优先考虑可读性,并且妨碍了高级思维。

最后,以我的经验,更好的语言和工具并不会导致产生更少错误的软件,而是导致更大的项目。pandoc1970年实际上没有任何合理的方式可以写成。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.