防止过度工程的方法?

时间:2009-11-09 16:15:52

标签: project-management

在开发软件时,我经常发现自己不断质疑“这是最好的方法吗?”“这项工作有更好的技术吗?”因此我加大力度进行实际调查研究不同的设计模式/技术/最佳实践,而不仅仅是用我知道的工具来开发工具!

我倾向于做的一件很常见的事情就是过早思考并担心可能发生的事情,而不是关注那些 的事情发生。我不相信这肯定是一件坏事,但是,我发现它有时会占用我太多的时间。

我想听听其他人是否有类似的问题以及他们如何解决这些问题?

28 个答案:

答案 0 :(得分:59)

截止日期。

答案 1 :(得分:40)

采用XP的想法...... YAGNI。 (You Ain't Gonna Need It

代码足以解决现在需要做的事情。让它满足您的客户的需求,无论如何,这一切都非常重要。 然后转到下一个功能。

如果你发现你需要重构一些东西,那么就这样,只需逐步进行。

答案 2 :(得分:30)

  1. 让它发挥作用
  2. 让它变得更好
  3. 时间不多了
  4. 按顺序。

答案 3 :(得分:16)

是的,我多次见过并经历过这个问题。头号解决方案(对我来说)是一个时间表。不是由在此处插入Black Magic 确定的营销部门时间表。我说的是每月/每季度的时间表,你对自己或你的团队造成“你说”在这个日期,我们必须有一个可构建的工作项目,如果他们当天取消我们的项目,他们仍然有一些好事。“

这样做是为了实现您必须承诺的真正里程碑。记住,里程碑是岩石。他们不动。同样,日历只是顺便提一下。如果你不能及时提出足够好的解决方案,那么你当天就不会有任何值得的。

我个人认为,对于中小型团体来说,为期三周的开发+ 1周的整合,测试,清理和最终准备是一个很好的安排。你的里程会有所不同。

答案 4 :(得分:10)

为防止过度工程,请执行此操作。

  1. 构建解决问题的最小,最简单的方法。

  2. 调查替代方案。

答案 5 :(得分:7)

很好的问题。这是我发现的,并不容易做到:

  1. 做原型。通过这种方式,我可以提前更深入地了解这个问题,而不仅仅是提前考虑问题,而且我从不让自己坚持使用次优代码。

  2. 获得真实软件实际性能调整的经验,因为至少根据我的经验,软件过度工程会导致大量性能问题,as in this case。这教会您典型的设计方法同时导致复杂性和缓慢性,因此您可以避免它们。一个例子是过分强调类的复杂性,数据结构和事件驱动的风格 (这与过早优化相反,通过尝试解决不存在的问题,最终会产生问题。)

  3. 有时候,我对软件简单性持有一种非常不妥协的看法,而且除了我之外,它似乎对所有人都很奇怪。例如,我偶然发现了Differential Execution的技术,它将UI代码缩短了一个数量级,并且很容易修改,但同时创建了很少有人攀爬过的学习曲线。

    < / LI>

答案 6 :(得分:7)

根据我的经验,避免过度工程的最简单方法是体验。虽然greenhorns会因为他们的疑虑和恐惧而无休止地挣扎,但是一位资深开发人员会这样做。他们会把它弄好(第二次,如果不是第一次)。

第二种最简单的方式就是信心。然而,这存在危险:如果没有经验,信心可能会非常危险。

这就留下了如何在短时间内到达的问题。世界上最伟大的思想正在努力。我的路径是使用自动化测试。这比其他任何事情都更快地杀死了我的恐惧和怀疑。它允许我将知识和经验从我的大脑转移到计算机上,所以我可怜的小脑子可以自由地接下来发生的事情,我不必担心我已经解决过的所有事情。

答案 7 :(得分:5)

Release Early, Release Often

即使您没有发布到外部客户端,您仍然可以向产品所有者或测试人员发布内部版本。这种工作循环使您更专注于手头的任务,而不是未来。

答案 8 :(得分:4)

练习YAGNI(你不需要它),你的生产力可能会提高。可能很多。

你可能想要阅读The Duct Tape Programmer,但是当你这样做时,请运用你的良好判断力。

答案 9 :(得分:3)

测试驱动的开发和重构意味着您不需要预先拥有最好的方法,甚至可以看到所有细节如何组合在一起......它是关于紧急设计

阅读背后的想法可能会帮助你减少对完美主义的担忧:http://c2.com/cgi/wiki?EmergentDesign

以下是我学习如何做到这一点:

  • 首先学习编写测试以获得一些简单的功能。
  • 然后编写满足测试的代码。
  • 寻找可以简化的重复元素或事物。在尝试简化/不复制代码之前,请确保所有测试都通过,以便您有重构的基准。
  • 重构后再次运行所有测试 - 确保您没有更改任何您关心的行为。
  • 检查。
  • 重复......直到完成......

  • 当你和其他人一起吃饭时,这更容易做...最好是那些已经知道如何做XP的人。

  • 过了一段时间,你学会了相信自己并接受你不需要在前面微小的细节中控制解决方案的所有部分......尽管首先开始处理风险/未知部分是有好处的。 ..

换句话说,学习XP; - )

答案 10 :(得分:3)

聘请一群软件架构师组成一个委员会来分析所有设计。

设计将以UML提交以简化分析。

所有项目都将使用内部基于XML的语言来避免使用单一语言的细节。

您还需要详细的编码标准,以避免工人过度工程。这应该只涵盖重要的事情,比如{}

的定位

答案 11 :(得分:2)

这是与同行进行审核应该有助于确定的事情之一。他们应该让你知道'你是否会进入杂草'(并且能够证明这种说法是正确的)。另一方面,他们也应该让你知道你是否还没有足够的并且正在设计一些脆弱且不够灵活的东西来改变或出现问题。

答案 12 :(得分:1)

听起来你没有项目经理。

您需要从着名的Rubber Duck Debugging窃取技术并将其应用于项目管理。假装Rubber Duck是代表主要客户的项目经理,并向其解释您希望花X小时研究新技术或新架构。现在假装橡皮鸭问你是否认为新功能的价值是客户资金的X * Y,其中Y是你的小时工资加上你的桌子和福利的成本。接下来,Rubber Duck会问您是否认为新功能延迟X小时交付产品。

诚实地回答Duck的两个问题,并根据您的回答继续进行开发。

很明显,你可能会问Duck是否他会在Stack Overflow上花费你所有的时间。

答案 13 :(得分:1)

有几种方法可以想到:

  • 专注于所提出的问题,并尽可能使要求尽可能清晰。前者可能被视为对某些人具有被动攻击性,因为完全按照要求做的并不一定是常见做法。
  • 留在当下,避免玩“假设”游戏,YAGNI。
  • 为工作留出时间,使其不是一直吸黑的黑洞。

其他一些需要注意的事项:

  • 避免因为你做的工作而殴打自己。无论你做什么,过去都会过去。
  • 应用程序的完美代码是一个神话。一个好计划的敌人是完美计划的梦想。
  • 虽然一些分析是好的,但使用审核来防止“分析瘫痪”

答案 14 :(得分:1)

使用部分CMMI;衡量自己。

找出一种方法来保持一个运行记录,表明你过度工程的次数与未工程的次数之比。弄清楚欠工程的痛苦平均花费了多少钱。等一两年,回头看看。

在短期内更多地考虑它可能对您有所帮助,从长远来看,您将获得数据,以了解您对过度工程的恐惧是否合理。

答案 15 :(得分:1)

保持简单,愚蠢

  

在讨论设计以抵挡渐渐的特征并控制发展的复杂性时经常引用的格言

http://en.wikipedia.org/wiki/KISS_principle

答案 16 :(得分:1)

您需要两件事:Timeboxing和Peer Review

Timeboxing就像说 - 我将花费N小时研究技术,以使这项工作更好。

Peer Review意味着您与其他感兴趣的工程师讨论此问题。

听起来好像你是在自己工作,这让Peer Review变得困难。我在Scrum商店工作。部分过程要求我们讨论所有修复和功能,然后在编写一行代码之前获得其他工程师的支持(协议)。这与“测量两次,切一次”相同。我们花费大约一半的时间进行研究和规划,值得投资。

答案 17 :(得分:0)

我发现防止过度工程化的最好方法是确保只编写与您目前所知的规范相同的代码。如果你有一个需要调用一个Web服务并检索一种类型数据的类,那么就不用费心去编写一些能够处理所有可能情况的非常强大的系统。

也就是说,这种技术真的非常需要您创建干净,编写良好,易于理解的代码,并要求您在任何地方都使用访问器。如果你不这样做,你最终会陷入重构的噩梦。

当您编写代码以仅满足您所知的内容时,您最终需要快速构建功能,当需求发生变化时,您可以返回并重构代码以添加缺少的功能。每次添加新功能时,您的代码都会(读取:应该)变得越来越好。

当然,在项目开始时需要做出一些总体设计决策,但这些决策的水平非常高,不应影响您按要求进行变更的能力。

在使用这种技术时,您需要花一点时间编写任何新模块,以问自己当前实现是否需要它,如果没有,请留下自己的评论并只写出所需的内容。

答案 18 :(得分:0)

避免过度工程并不是那么难,你只需要务实......

  1. 获取用户故事
  2. 制作用户故事中的用例
  3. 为第一个用例的第一个功能编写单元测试
  4. 实施功能
  5. 如有必要,请使用SRP分割太大的类
  6. 转到下一个功能
  7. 转到下一个用例
  8. 完成后,您可以将API(例如REST)和数据库(例如PgSQL)添加到您的应用程序(这部分取决于您遵循的开发模型)。
  9. 通过使用TDD,您不必规划完整的类层次结构或理解整个项目,您只需编写一小段代码或立即进行测试。只关注你真正需要的东西,这有很大的帮助......

    我目前正在试验clean architecture,它通过构建易于测试,可开发和可维护的应用程序,对TDD非常有效。

答案 19 :(得分:0)

有一个可靠的原则可以遵循:先完成任务,然后再聪明。你必须实现第一个目标,第二个目标不是。

答案 20 :(得分:0)

只要你达到你的时间目标 - 尽可能多地投资。 如果你无法达到你的时间目标......只有当你认为满足要求是至关重要的,或者如果你认为你正朝着一个如果出错而无法修复的方向进行投资......

答案 21 :(得分:0)

时间拳击是我们的工作。

我们将对即将发生的问题进行为期3天的调查,并尝试一些方法并选择解决方案。

在运行之后并且经常提前交付,在您展示了一些进展之后,如果有更好的答案,您可以重构。

答案 22 :(得分:0)

我试图平衡我花在调查和设计上的时间与我可以合理预期其使用和生命周期的时间,从而避免过度工程或工程不足。

假设我正在编写一个只会使用的实用程序,我很少使用它,甚至只使用一次。如果我可以选择在Bourne shell中编写这样的实用程序,或者在10分钟内编写一个需要隔夜运行的Perl,并花费三个小时来编写一个优化版本,使用在一分钟内运行的C ++中复杂而困难的算法...比我的时间便宜。

另一方面,我编写了多年来已被数百万人使用或影响数百万人的产品的关键组件。在这种情况下,花费时间和精力花费大量精力进行调查,研究和设计,使用绝对最好的工具和技术,然后将生成的代码抛光到光泽闪耀是值得的。

没有一刀切的方法 - 这都是判断力。正如Aaron Digulla恰当地指出的那样,经验非常有用,经验非常有用。

二十四年前,当我作为一名专业软件开发人员开始时,我并不知道如何做出这些决定。我只是编写代码,如果它太慢或太麻烦或什么的,我会回去修复它。但是当我做了那个修复时,我会试着想一想我如何能够首先避免这个问题,以及我将来如何应用它。当他们谈论他们遇到的问题以及他们如何修复问题时,我也试图听取其他程序员的意见。

现在,许多项目以及之后的数百万行代码,我可以做出很多本能的设计决策。例如:“如果您正在使用C ++,并且您遇到了某个STL模板将要解决的问题,并且您没有被限制以避免使用STL,那么这就是要走的路。这是因为现代STL实现是高度优化,您可以通过编写自己的代码获得的任何改进都是不值得的。“

另外,我可以看一下情况并说:“我们可能遇到问题的项目的10%就在这里,在这里,在这里,这就是我们需要集中研究和设计的地方努力。另外90%,我们可以做到,但我们可以做到。“它运作得很好。

因此,请继续编码,不断改进代码,并不断向其他软件开发人员和您自己的经验学习。如果你继续关注并思考问题,那么随着时间的推移,软件设计的掌握程度会越来越高。

答案 23 :(得分:0)

另一种方法是定期检查你所做的所有事情并将其重构为骨骼:删除所有不需要的东西。根据需要重复。使代码更精简,用于下一次迭代。

此致

答案 24 :(得分:0)

  • 选择适合您的解决方案,除非您受到当前限制,否则不要尝试查找其他内容(墨菲:如果没有损坏,请不要修复)
  • 创建列表o优先级并坚持下去。

答案 25 :(得分:0)

专注于统一流程中最关键功能的增量可交付成果的设计旨在解决此问题。实施需要纪律。

制作功能列表(用例),确定其优先级,选择最高优先级并对其进行处理,就像它是您需要的唯一功能一样。当您以工作形式交付时,再次分析并选择要处理的下一个功能集。

答案 26 :(得分:0)

我经常遇到这种情况。如果我需要用我经常使用的语言来解决某些东西,现在是JavaScript,我就陷入困境,我尝试使用新的框架解决问题。有一些关于使用新工具,新代码库,甚至是我通常不会使用的浏览器的东西,这有助于我克服尝试正确做法的心理障碍。

答案 27 :(得分:0)

过早优化和处理ifs肯定是个问题。

一般的想法是确保您拥有尽可能最好的代码,并愿意在学习时采用更好的实践。

总的来说,解决当前已知问题的最简单答案通常是最好的。但是,您的代码应该能够捕获意外的错误情况并记录/公开它们,以便为这些极端情况添加更强大的处理。