专业软件开发团队如何处理非平凡项目中的设计复杂性?


9

首先,我意识到这个问题可能会有些冗长和含糊,为此我深表歉意。对于任何“了解它”的人来说,这可能是一个简短的基本问题,但由于我发现自己在这方面缺乏经验,因此请在描述问题时请多多包涵。

从我11岁左右开始,我就一直以这种方式进行编程。这意味着我从一开始就一直在教自己。我接受了技术教育,但并非严格地学习计算机科学(我获得了光子工程学学位)。我们当然有编程课程,但这对我来说基本上是基本的东西,我没有学到很多新东西。我一直在为自己的快乐而进行自我教育,并且一直知道自己会从事编程事业,但是那时我的所有项目都还很小。我毫不费力地将它们牢记在心并加以维护。

现在,我发现自己是团队的领导者,而不是公司环境的领导者-我在大学工作,开发用于工程应用的科学软件(C ++)。突然间,这个项目正在(相对)变大,而且我大部分时间都无法解决这个问题。我主要在两件事上浪费了很多时间和精力:

  1. 当我不得不返回一段时间未使用的代码时,我很难记住它是如何工作的。我花了很多时间来查看相关类的头文件,并阅读在源文件中放置的注释。我希望我可以瞥见某种形式的“示意图”并更轻松地重获图片。
  2. 当我引入更改时,有时我会中途意识到,我试图做的事情会破坏其他地方的功能(或更糟糕的是,它只会在运行时显示出来,这是一个惊喜)。我还原并开始以不同的方式进行操作,结果发现我忽略了对其他组件的影响。我希望有一些“架构图”,在其中可以看到事情的完成方式,我要尝试做的事情将如何影响其他组件,以及为我提供一种在开始实施更改之前进行详细规划的方法。

与我一起工作的大多数人都有与我自己相似的故事-较强的技术导向,有时甚至是高超的技巧,但无法组织工作。但是,他们的项目通常比我的项目小得多,所以他们可以应付。无论如何,这对我来说意味着我一个人,没有人可以学习良好的做法。

我修了一个管理IT的研究生课程,尽管我觉得它很令人满意,但它主要针对非程序员,有关项目管理方法论,预算/进度估计,企业体系结构的教学,而不是软件设计和规划。没关系,我也在尝试学习这些东西。当然,引入了一些工具(例如UML)和软件开发过程的类型(级联,迭代,敏捷...),但是显然没有详细介绍,我很难决定我应该选择和使用的东西(以及达到什么程度)。

我一直在阅读有关SO上软件设计的许多问题和答案-有很多关于使用这种工具或特定工具或方法进行设计的问题,并且如果我确信UML文档可以解决我的问题-我会选择并开始使用它。但是有些人发誓,其他人则说它没用。我正在寻找更高层次的抽象的答案-有解决我所遇到的两个问题的方法吗,您个人怎么做?我应该学会什么才能做到这一点,而不必局限于某个特定工具?这些有时会变得过时,我希望它们的适用性会因项目类型而异。

非常感谢您的阅读,我无法简要地说出我的意思(缺乏软件设计经验和词汇)。


2
我认为,针对您所遇到的困难,最常见的专业应对方法是“操之过急”,然后指责管理,产品或其他一些随机的SOB。
爱德华·斯特朗奇

Answers:


9

当我不得不返回一段时间未使用的代码时,我很难记住它是如何工作的。我花了很多时间来查看相关类的头文件,并阅读在源文件中放置的注释。

想象一下您之后出现的那个可怜的家伙会有什么样的感觉-他甚至没有曾经知道您的代码如何工作的好处。您应该查看为该模块编写的文档,而不是尝试破译代码。该文档应提供有关模块做什么原因的合理准确视图。它不是“该模块通过使用三元组for循环初始化三个数组来开始...”,而是:“该模块检索由Fabulotron主传感器收集的数据,将其重新排列为标准Neopolitan(巧克力,香草,草莓)格式,并将其交付给“分析”模块。”

在理想的情况下,您将拥有一份设计文档,其中列出了系统中的各个模块并描述了它们各自的职责,并且每个模块都可以参考该文档来说明它们的工作:“此模块提供了Fabulotron数据收集服务,如设计文档第4.8节中所述:http//fabulotron.org/design/section4-8.html。” 如果没有这样的内容,请在编写每个模块时开始写下概述。您无需写书-只需写几段就足以使您适应新的需求。

当我引入更改时,有时我会中途意识到,我试图做的事情会破坏其他地方的功能(或更糟糕的是,它只会在运行时显示出来,这是一个惊喜)。我还原并开始以不同的方式进行操作,结果发现我忽略了对其他组件的影响。

这可能表明您的模块之间互连太紧密。使模块/类/单元越独立,遇到这种问题的可能性就越小。尝试使模块之间的接口尽可能明确,并尝试将它们限制为仅需要存在的接口。接口是一种合同-如果您知道某个模块能够履行其在接口中指定的义务,那么您无需了解其他任何内容。这样可以防止您正在处理的模块中的更改影响其他模块。

我希望有一些“架构图”可以看到事情如何完成

使用标准零件可以在这方面有所帮助。C ++以标准模板库的形式提供标准部分,并在适当的地方使用这些部分可以使您处于更高的抽象水平。如果您编写了自己的代码来管理诸如列表之类的数据结构,则您和之后的那些人将不得不不断阅读源代码以了解正在发生的事情。如果您改用STL提供的标准部件,则任何C ++程序员都可以很快地分辨出代码在做什么,而无需深入研究数据管理例程。

另一种标准零件来自设计模式。它们是标准概念,可以用作简写来解释两个对象之间的关系如何工作。


感谢您的回答。当然,我已经使用STL多年了,但是,即使使用了STL,我的程序执行人为计算的步骤也有时难以完整地描绘出来。模块也是如此。我并不是说改变一个人会破坏另一个人,而是在某处进行改变会引起故障,例如,当用户在GUI中执行非标准的操作时,复杂的序列会因无法完成的步骤顺序而变得更加复杂。
neuviemeporte 2012年

5

我只是短时间的专业开发人员,刚开始时就为如何做到这一点而苦苦挣扎。我主要是自学成才,即使是大学。对我来说幸运的是,我与之共事的人都有很多经验,并且能够教我有关大型项目的管理和工作方式。

我要做的第一件事就是坐下来阅读干净的代码。这是一本很棒的书,它帮助我了解了如何编写当我回过头来还是别人可以理解的代码。

第二件事是编写高质量的测试,单元,集成,验收。如果您的代码经过了良好的测试,您将很快知道何时破坏了某些内容,并能够迅速诊断出问题。互联网上有很多好的测试资源,我不确定哪一种是最好的建议。

我的重点是测试和清洁代码。


感谢您的建议,我将确保检查出本书(即使副标题中的“敏捷”似乎表明它与该方法学最相关)。我确实有测试,并且已经阅读了许多编码风格的书(例如Pragmatic Programmer),我一直在努力创建干净且分隔良好的界面,但是对于我的应用程序的GUI部分来说,进行一次自动化测试是很困难的,而且我仍然没有大规模进行良好总体设计的方法,不只是在相对较小的代码块上实施“干净”的做法。
neuviemeporte 2012年

2

这是组织大型软件系统的一些高级思路。我的大部分经验是在Internet系统上,但我认为这些想法适用于工程软件。

  • 将功能分成相对隔离的模块化块。例如,您可能为软件提供的每个计算系列都有一个模块。
  • 如果有的话,将MVC设计模式应用于用户界面。保持界面和模型之间的界限明确。
  • 考虑使用图层对模块进行分组。在使用抽象层的应用程序中,每个层仅取决于其下面的层。
  • 编写文档时,假设您会忘记所有实现细节。在这种假设下,您将编写大量文档-也许多达一半的代码将是注释,但是以后您将不会感到困惑。
  • 自动化的单元测试,集成测试和验收测试在某些方面很棒,但是C ++开发人员似乎对此有不同的感觉。
  • 大量借鉴设计模式。除了通常是好的主意之外,设计模式还提供了软件工程中的常用词汇。将类称为WidgetFactory是一种简洁的方式来传达它是存在于制作小部件的类的信息。

自从我使用工程软件以来已经有很长时间了,因此您的建议可能会有所不同。祝好运!


1

答案是软件工程。

也就是说,对于大型项目,您在执行任何实际编码之前就遵循了一系列要求收集,过程定义,规范等顺序。

取决于环境和文化,使用了各种方法。企业类型的业务倾向于遵循“ Rational Unified Process ”或类似的方式,技术初创公司通常会在敏捷方面有所变化,政府部门会采用一些过度的瀑布方法。

在所有情况下,该过程都可以帮助您准确定义正在执行的操作,并在项目结束时让您证明自己已完成操作。


假设需求没有改变(在许多情况下,这是不切实际的假设,我知道),实际上是否可以在编码之前指定所有内容,然后在不进行重大改动的情况下从规格创建适用的软件?我就是无法想象。我必须开始编码才能体会。稍微调整,再调整一些,等等...
neuviemeporte 2012年

这可能适用于小型项目,但是对于大型项目,您需要首先处理需求。RUP的重要组成部分是使用UML和序列图对建议的系统进行建模。它比实际代码更容易调整和重构模型。
詹姆斯·安德森

@neuviemeporte:这取决于。有时,需求变更或在开发过程中发现新需求。有时需求从一开始就很明确,在开发过程中只有一些次要细节会发生变化,但总体架构将保持不变。
乔治

1

我强烈建议您使用Enterprise Architect,它虽然不是免费的,但确实提供学术价格。这是用于从宏观和微观两个层次上绘制项目的出色工具。它还可以将您的源文件反向工程为类图,这对于您记录和重新组织应用程序的组合方式可能是一个不错的开始。

我还要第二个@Klee的建议。不要被所谓的“敏捷”工具拖延,因为它们实际上只是最佳实践,如果您遵循敏捷过程,它们也很方便(如果不是强制性的)。但是,无论您采用哪种方法,持续集成(例如)都很有价值。此外,单元测试(cppUnit?)是您的朋友。如果您测试UI调用的逻辑类,而不是直接测试UI,则单元测试应该非常可行。还有一些工具可以帮助您自动化UI测试,但是我会尝试先将后端的东西放在一起。

祝好运!


1

我相信你的问题有三个方面

  1. 面向程序员
  2. 面向程序
  3. 程序维护-面向

关于第一个问题,您可能会有不了解程序功能概念的程序员(这通常发生在公司设置中)。但是按照您的问题和您所处的领域来看,您和您的团队似乎可以控制程序的工作,但是无法迅速将其转换为工作程序(举个例子,我听说过人们拥有物理学博士学位后难以理解编程的指针,我相信物理学比C ++困难得多。如果是这样,那么您的问题主要是以程序为中心的(您必须非常幸运,周围的人才能了解您的程序在做什么,并且可以欣赏它)。

如果遇到以程序为中心的问题,我的一个不合理的建议是将其提升到比C ++更高的抽象水平,例如学习一种新的语言,例如Python或Haskell(Python非常容易学习,如果您有优秀的数学家, Haskell很棒)。转移到更高的抽象级别将使您的代码尺寸减小,从长远来看易于理解和维护,并且效果会迅速变化。因此,您可以用10行代码代替原来的50行代码。同样,拥有一个精通计算机编程知识的人肯定会有所帮助。在大学里,您还可以吸引一些学生使用GUI和界面,以便您可以更加专注于功能。我还推荐John Lakos撰写的《大规模C ++软件设计》一书(这是一本相当大的书,您可能会花很多时间来读一本书,成为熟练的Python程序员)

如果您从问题的前两个维度中挑选出来,第三个维度将自动得到解决。由于我相信您正在从事一个大型项目,因此您可以使用任何不错的项目管理软件。预先计划是必要的。如果您立即开始编码,则可能会过多地参与该程序,而您可能会忘记总体情况。牢记事项对于大型项目是行不通的。将所有物品都放在纸上(或计算机上)。使用维基共享信息。关于方法论,我更喜欢敏捷方法论(简单地说,敏捷是用于增量软件开发的时髦名称)。我还建议雇用在这一领域有专长的人,以便他照顾这些人,以便您可以专注于核心计划。最重要的是,所有项目管理方法论都是确保程序成功的一种方法。因此,您可以选择最适合您和您团队的人,而不必选择别人推荐的最佳人选。另外,以下软件也可能帮助您

  • Free Mind-思维导图软件
  • Trac-快速简便的软件错误程序和Wiki
  • MoinMoin-快速Wiki,可实现有关程序的知识共享

尽管从长远来看,上述技巧会花一些时间学习它是值得的。最后,编程比光子工程更容易(尽管不是C ++编程)


0

像您的问题一样,任何对您有用的答案都会非常冗长和模糊-但简短的答案是“软件工程”

如果您对软件开发事业很认真,建议您花一些空闲时间,并从访问Steve McConnells网站开始。编程很容易,并且可以在一个学期内教授。软件工程要复杂一个数量级,需要更长的学习时间。

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.