与在代码中完成所有工作相比,对软件系统进行建模有什么好处?


20

我认识的大多数(如果不是全部)IT人员相信,在编码之前使用UML或其他类型的图对软件进行建模是有益的。(我的问题不是专门关于UML的,它可以是软件设计的任何图形或文本描述。)

我不太确定。主要原因是:代码没有说谎。它由编译器或解释器检查。希望它具有自动化测试,并且需要通过静态代码分析。如果一个模块不能与另一个模块正确连接,则在代码中通常很明显,因为会收到一条错误消息。

使用图表和其他文档无法完成所有这些操作。是的,有些工具可以检查UML,但是到目前为止,我所看到的一切都非常有限。因此,这些文档往往不完整,不一致或简单。

即使图本身是一致的,您也不能确定代码是否实际实现了它们。是的,有代码生成器,但是它们从不生成所有代码。

我有时会觉得对建模结果的痴迷是因为这样的假设,即代码不可避免地必须是一些不可理解的混乱,而建筑师,设计师或其他掌握高薪的高薪人士则不必处理这些混乱。否则,它将变得太昂贵。因此,所有设计决策都应远离代码。代码本身应该留给能够写(甚至可以读)但不必处理其他任何东西的专家(代码猴子)。当汇编程序是唯一的选择时,这可能很有意义,但是现代语言允许您以很高的抽象水平进行编码。因此,我真的不再需要建模。

我缺少用于建模软件系统的哪些论据?

顺便说一句,我相信图是一个伟大的方式来记录和沟通软件设计的某些方面,但是,这并不意味着我们应该立足于他们的软件设计。

澄清:

由于不清楚,这个问题被搁置了。因此,让我添加一些解释:

我在问使用将软件建模的(非代码)文档作为有关软件设计的主要事实来源是否有意义。我没有想到从这些文档中自动生成很大一部分代码的情况。如果是这种情况,我会将文档本身视为源代码,而不是模型。

我列出了此过程的一些缺点,这使我想知道为什么有这么多人(以我的经验)认为它是进行软件设计的首选方法。



5
我认为这是一个完全有效的问题。如果我们的模型具有任何值,则必须与代码匹配。那么为什么不使用我们以后用来实现模型的语言来设计模型呢?然后它们始终保持同步。而且,如果您喜欢精美的图形,则可以从代码中生成它们。
Ralf Kleberhoff

3
然后,您应该认识更多的“ IT”人员。也许我应该说,您应该熟悉该保护伞内的更多社区。
德里克·埃尔金斯

@DocBrown:虽然该问题的答案,尤其是您评论中链接的文章确实提供了相关信息,但原始问题却大不相同。
Frank Puffer

@FrankPuffer:我知道,投票重新开放。不过,我认为您的问题的核心-“什么是软件设计”和“建模在软件设计中的作用”是一个非常广泛的问题,可能范围太广,无法在此处以明智的方式回答。
布朗

Answers:


23

相对于全部代码,对软件系统进行建模的好处是:我可以在白板上拟合模型。

我坚信在一张纸上进行交流的魔力。如果我试图将代码放到白板上,那么在向新编码员讲授我们的系统时,根本没有适合白板的任何需要的抽象级别的代码。

我知道您所指的是对建模的痴迷。人们做事是因为这是他们以前做过的事情,而没有考虑他们为什么这样做。我来称它为形式主义。我更喜欢非正式地工作,因为很难将愚蠢隐藏在传统背后。

这并不意味着我不会不时地抽出UML草图。但是我永远不会是要求您在编写代码之前上交UML文档的家伙。我可能会要求您花5分钟时间,并找到某种方式来解释您的工作,因为我无法忍受只有一个人能理解的代码。

Fowler指出了人们使用UML的不同方式,他称之为UML模式。所有这些工具的危险之处在于,它们可能会被用来隐藏进行有用的工作。如果您正在使用鼠标进行编码,那么我已经看到了很多尝试。尚未见任何人真正做到这一点。如果您要与他人交流,最好确保其他人理解您。如果您要进行设计,那就更好了,那就是在工作时发现并解决问题。如果一切进展顺利,并且您花费了大部分时间使箭头看起来不错,然后将其关闭并恢复工作。

最重要的是,不要产生您希望一天以上有效的图表。如果可以,您就失败了。因为软件本来就很软。不要花数周的时间使图表正确。告诉我发生了什么。如果需要,请使用餐巾纸。

也就是说,我更喜欢知道UML和设计模式的编码人员。他们更容易沟通。只要他们知道生成图表并不是一项全职工作。


2
“根本没有适合白板的抽象级别的代码”,这提出了一个有趣的问题。为什么不?要使系统的入口点在很高的层次上解释其作用,那是什么?
RubberDuck

2
因为代码必须对所有人(以及至少一个编译器)都是万能的。模型可以有一个专门的受众。
candied_orange

我认为为此使用“形式主义”一词是不幸的。它要么夸大了“建模者”的工作,要么贬低了实际的形式化建模。(它似乎也并不能从我在这里所说的内容中真正抓住您的意图。您的关注点似乎并不在于建模本身,而是将其用作大门或出于官僚原因,即使它没有增加价值。)
德里克·埃尔金斯

3
我的问题不在于建模。它使用正式的仪式代替批判性思维。我想说的是,发生了很多模型抨击事件,因为很多模型都落在了那群人中。建模可以非常好。但是它有阴暗面。
candied_orange

1
“我可以在白板上拟合模型”是一种非常具体(非常好!)的说法,“我可以抽象一些较复杂的东西,以帮助理解或传达我认为重要的方面。” 好的建模通常是这样做的,无论是软件还是其他复杂的事物。
Fuhrmanator

6

我在问使用将软件建模的(非代码)文档作为有关软件设计的主要事实来源是否有意义

不。这永远都没有道理。您的代码是您的主要设计文档,即“有关软件设计的主要事实来源”。当编译器采用该设计并从中创建应用程序时,只有代码准确地描述了应用程序的功能。

一定要使用图表作为补充设计文档,尽管如果它们不是从代码中自动生成的,请当心它们会告诉真实设计一个不同的故事。如果UML使您的船浮起,请使用它。如果没有,请使用其他东西。

一些人发现在开始编写代码之前以图表的形式勾勒出他们的想法很有用。但是请记住鲍勃叔叔在这件事上说了什么:

所以,是的,图有时可能是不合适的。什么时候不合适?当您创建没有代码的图形来验证它们,然后打算遵循它们时。绘制图来探索一个想法并没有错。

如果您确实使用UML探索设计,请在开始编码时将其丢弃。编写测试,然后编写一些代码以使其通过。重复。这样,您将获得经过验证的设计。UML永远无法为您提供相同级别的设计验证。


一个反例(?)::模型视图分离(或任何GoF模式)可以很容易地绘制为建筑师提出的设计意图(蓝图)。偏离此意图的开发人员不会使(预期的)模型失效。是的,代码是“真相”,但不一定是设计。使用UML或某些模型进行验证不一定是自动的。事实并非如此,这并不能使模型成为垃圾箱。
Fuhrmanator

至于测试,我不确定验证设计是否有用。您是否可以编写表明域逻辑不在表示层中的测试(与预期设计背道而驰的实现中的一个非常普遍的问题)?向开发人员显示这些层的示意图,并说明一种actionPerformed()方法位于表示层中,并且该方法应将控制权简单地传递给域层,这是分离的关键方面。(仅举一例,但它可以应用于所有难以仅用代码展示的设计策略)。
Fuhrmanator

5

我认识的大多数(如果不是全部)IT人员相信,在编码之前使用UML或其他类型的图对软件进行建模是有益的。

我不同意您认识的所有人都相信这一点,但是我认为这不一定在所有领域都是普遍的。1970年,温斯顿·罗伊斯(Winston Royce)知道软件开发在设计和代码活动之间存在一定程度的迭代。1992年,杰克·里夫斯(Jack Reeves)撰写了有关编码是真正的设计活动的文章(也在C2 Wiki上进行了讨论)。

这并不意味着人们已经尝试制作模型驱动的开发工具。有一些工具尝试从UML模型生成代码(而不仅仅是类图,而是将各种图类型链接在一起并从中生成代码)。但是,至少从我所见,这些工具并不是广泛使用的工具。

这也不意味着您应该从需求入手编写代码。某些设计决策对于及早实施至关重要,并且一定程度的建模对于确保每个人都理解选项,影响以及进行沟通非常有用。有些人(包括我自己)将其称为“软件体系结构”

代码没有说谎。它由编译器或解释器检查。希望它具有自动化测试,并且需要通过静态代码分析。如果一个模块不能与另一个模块正确连接,则在代码中通常很明显,因为会收到一条错误消息。

这确实是敏捷建模某些方面的心脏,尤其是可执行规范单一信息源。我不一定同意TDD,但是让您的代码和相关测试(从单元测试到验收测试,最好是作为自动测试捕获)是唯一的真理是这样的想法。

即使图本身是一致的,您也不能确定代码是否实际实现了它们。是的,有代码生成器,但是它们从不生成所有代码。

我认为一般来说,从模型->代码开始是错误的方法。相反,代码应生成模型。也就是说,工具应该能够检查代码并生成图形和表格表示形式,当工程师围绕它们编写文本时,可以进一步增强这些功能。从代码中生成的模型应该成为构建和发布过程的无缝部分。

有些工具在不同程度上确实支持各种语言。鉴于语言和范式的本质,对于某些语言和范例而言,它比其他语言容易。

我列出了此过程的一些缺点,这使我想知道为什么有这么多人(以我的经验)认为它是进行软件设计的首选方法。

我认为这些人不一定了解软件工程和软件设计。我认为这些人正在研究其他工程学科在做什么,并将其映射到他们认为软件工程师应该做的事情。但是他们忽略了一个主要差异。其他工程学科首先创建模型和仿真,因为构建实际产品非常昂贵且耗时。在软件工程中,我们可以花费很少的时间和很少的成本来完成我们的设计工作,并产生可以在现实环境中进行测试的产品。经济学有很大的不同。

与在代码中完成所有工作相比,对软件系统进行建模有什么好处?

当您拥有极其复杂的软件系统时,拥有模型意味着拥有更容易理解的东西。它是不同的抽象级别,可以帮助人们理解系统的各个方面。这就是为什么每种建模语言或符号允许这么多不同的建模语言和不同类型的模型的原因之一-允许不同的涉众从概念上快速轻松地理解软件系统。


5

我在问使用将软件建模的(非代码)文档作为有关软件设计的主要事实来源是否有意义。我没有想到从这些文档中自动生成很大一部分代码的情况。如果是这种情况,我会将文档本身视为源代码,而不是模型。

大量非代码文档可用作蓝图。也就是说,设计的“真相”应该遵循这个方向。这是对设计必须满足的元素进行建模的一种方式。您可以将它们称为需求文档,但是在我能提供的所有示例中,这可能太强大了。我已经通过PlantText.com使用PlantUML 来生成这些。

  • 用例图可以显示预期的功能以及与用户或外部系统的交互。 在此处输入图片说明

  • 活动图可以显示软件需要支持的业务流程。 在此处输入图片说明

  • 状态图可以显示网站上的预期动态: 在此处输入图片说明

  • 四种设计模式的组合以静态和动态模型的形式呈现。例如,Memento:
    在此处输入图片说明
    在此处输入图片说明

我列出了此过程的一些缺点,这使我想知道为什么有这么多人(以我的经验)认为它是进行软件设计的首选方法。

如果您在经验之外还对有关UML使用的某些真实信息感兴趣,请进行一些研究(我试图找到非付费专栏文章的链接):


0

我们的开发人员喜欢用图像来解释我们的世界,所以这里有一辆汽车:

  • 汽车是生产链的结果,代码也是一样的(当然要加上部署过程)。
  • 汽车的设计文件与软件的设计文件相同。

在我们的世界中,通常比那些构思和制作设计文档的人与产生代码的人相同。在其他领域则不是这样。但是,这并不意味着您真的可以通过将它们全部组合在一起而达到相同的质量水平。

通过首先制作这些文档而无需编码(不包括类似概念证明的可行性,...):

  • 您一定会在做事之前思考一下,一旦知道要做的事就是轻松就可以进行编码。
  • 您可以让更多有经验的人专注于软件的最困难部分:设计,算法/运算法则可以用于非常特定的目的(嵌入式,实时,汇编)。
  • 您可以将经验不足的人的大部分工作委派给编码人员,而经验丰富的人则只专注于需要他们技能水平的最关键部分。那些经验不足的人会学到很多。
  • 您可以通过设计文档的图像与非IT人员进行讨论,而如果您只有代码,则必须提取您所做的图像,否则就有可能忘记某些东西(某个地方被遗忘的侦听器)。有关沟通的更多信息,请参见CandiedOrange的答案。
  • 当您必须使软件不断发展时,您可以更好地预期会产生什么影响。
  • 设计将使您可以轻松地缩减您的软件片段并同时开发您的软件。
  • 当您不必为编写代码时涵盖所有情况而烦恼时,以TDD方式编写代码,然后再编写代码就很容易了。
  • ...

注意:这些确认假设代码确实是设计的反映,并且它们都保持最新状态...


该答案描述了一种近乎最佳的情况。您最后提到一个警告,它本身就很大。还有很多。您可以轻松地省略必要的方面,低估某些部分的复杂性,不考虑您使用的库/框架的约束,不考虑依赖项中的错误,不考虑性能或其他非功能性需求,过度设计,无法预期更改,或者根本不擅长设计。即使在专业背景下,这种最佳情况也不太可能实现。
德里克·埃尔金斯

如果您仅考虑所有事项,那么您将一事无成。无论使用哪种方法。仅执行代码时,一长串您所说的内容就完全有效。
Walfrat
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.