如何防止过度工程?
在开发软件时,我经常会发现自己不断质疑“这是最好的方法吗? “这个工作有更好的技术吗?” 因此我花了更多的精力去研究和研究不同的devise模式/技术/最佳实践,而不是用我所知道的工具来开发工具。
我倾向于做的一件事情是想得太远,担心可能发生的事情,而不是集中在将要发生的事情上。 我不相信这不一定是件坏事,但是我觉得有时候会花费太多的时间。
我想听听其他人是否有类似的问题,以及他们如何解决这些问题?
采用XP的想法… YAGNI。 ( 你不会需要它 )
足够的代码来解决现在需要做的事情。 让它达到客户满意的程度,无论如何这都是非常重要的。 然后转到下一个function。
如果你发现你需要重构一些东西,那么就这样做吧。
最后期限。
- 让它起作用
- 做得更好
- 没有时间
以该顺序。
是的,我已经多次看到并经历过这个问题。 头号解决scheme(对我来说)是一个时间表。 在这里插入黑魔法不是一个市场部门的时间表。 我正在谈论的是像你每月/每季度的时间表,你在自己或你所在的小组中所说的话,“在这个日子里,我们必须有一个可build立的工作项目,如果他们那天取消了我们的项目,他们仍然有一些好的东西。“
这样做是把真正的里程碑,你必须承诺。 请记住,里程碑是岩石。 他们不动。 同样,日历只是嘀嗒而已。 如果你不能及时提出一个足够好的解决scheme,那么在那一天你就没有什么价值。
就我个人而言,我认为对于中小企业来说,三周的发展+一周的整合,testing,清理和最后准备是一个不错的安排。 你的里程会有所不同。
是。
为了防止过度工程,请执行此操作。
-
build立解决问题的最小,最简单的事情。
-
调查替代品。
根据我的经验,避免过度工程的最简单的方法就是经验。 虽然新手们会因怀疑和恐惧而无休止地挣扎,但一位高级开发人员只会这样做。 他们会做对(第二次,如果不是第一次)。
第二个最简单的方法是信心。 但是,这存在一个危险:没有经验,信心可能是非常危险的。
这就让问题在短时间内如何到达。 世界上最伟大的人正在努力。 我的path使用自动化testing。 这比其他任何事情都更快地消除我的恐惧和疑虑。 它使我能够将知识和经验从我的大脑转移到计算机上,所以我可怜的小脑袋为下一件事而自由,我不必担心所有已经解决的事情。
很好的问题。 以下是我find的,这并不容易:
-
做原型。 通过这种方式,我对这个问题的了解比以往任何时候都能得到更深刻的理解,而且我永远不会陷入次优代码的束缚之中。
-
获得有关实际软件实际性能调整的经验,因为至less根据我的经验,过度devise软件会导致巨大的性能问题, 就像这种情况一样 。 这教导你什么典型的devise方法同时导致复杂性和缓慢,所以你可以避免它们。 一个例子是过分强调类的错综复杂,数据结构和事件驱动的风格。
(这与过早优化相反,在这种早期优化中,试图解决不存在的问题,最终会产生问题。) -
有时候,我对软件的简单性采取了非常不妥协的观点,而且除了我之外,似乎对每个人都是非常奇怪的代价。 例如,我偶然发现了差分执行的技术,它将UI代码缩短了一个数量级,使其非常容易修改,但同时创build了几乎没有爬过的学习曲线。
提前发布,经常发布
即使你没有发布到外部客户端,你仍然可以向产品所有者或testing人员发布内部版本。 这种工作周期使您更专注于手头的任务而不是未来。
练习YAGNI(你不会需要它),你的生产力可能会上升。 可能很多。
您可能需要阅读The Duct Tape Programmer ,但是当你这样做的时候,你应该做出正确的判断。
testing驱动的开发和重构意味着你不需要事先做好最好的方法,甚至不需要知道所有的细节如何结合在一起……这是关于紧急devise的 。
阅读这个背后的想法可能会帮助你更less担心完美主义: http : //c2.com/cgi/wiki?EmergentDesign
以下是我学会如何做到的:
- 学会先写一些简单的functiontesting。
- 然后编写满足testing的代码。
- 寻找可以简化的重复或事物的元素。 在尝试简化/不复制代码之前,请确保所有testing都通过,以便重构基准。
- 重构后再次运行所有的testing – 以确保你没有改变任何你关心的行为。
- 检查它。
-
重复…直到完成…
-
当你和其他人打成一片时,这样做比较容易…最好是已经知道如何做XP的人。
- 一段时间后,你会学会相信自己,并接受你不需要在前面细微的细节中控制解决scheme的所有部分…虽然开始处理风险/未知部分是值得的…
换句话说,学习XP 😉
聘请一批软件架构师组build一个委员会来分析所有的devise。
devise将以UML提交以简化分析。
所有项目都将使用内部基于XML的语言来避免单一语言的细节。
您还需要一个详细的编码标准,以避免工人过度工程的事情。 这应该只包括重要的事情,如定位{}
这是与同行进行审核应该帮助确定的事情之一。 他们应该让你知道,如果你“进入杂草”(并能够certificate这一说法)。 另一方面,他们也应该让你知道,如果你做得不够好 ,正在devise一些脆弱的,没有足够的弹性来改变或问题。
使用CMMI的一部分; 衡量自己。
想出一个方法来保持多less次你过度工程师与多less次underengineer运行的计数。 找出多less痛苦underengineering平均花费你的东西。 等一两年,然后回头看看。
更多地思考这个问题可能会在短期内帮助你,而且从长远来看,你将获得数据来了解你是否对过度工程的恐惧是合理的。
有几种方法可以想到:
- 关注所要求的内容,尽可能使要求尽可能清楚。 前者可能被视为被动的侵略性,因为所做的事情并不一定是通常的做法。
- 留在这一刻,避免玩“假如”游戏,YAGNI。
- 时间框的工作,使它不是黑洞吸所有可用的时间。
其他一些事情要注意:
- 不要为了做你做的工作而殴打自己。 无论你做什么,过去都会保持过去。
- 一个应用程序的完美代码是一个神话。 一个好的计划的敌人是完美的梦想。
- 虽然有些分析是好的,但要用适度的方法来防止“分析瘫痪”
你需要两件事:时间盒和同行评审
时间安装就像说一样简单 – 我会花费N小时研究技术,使这项工作更好。
同行评审意味着你与其他感兴趣的工程师讨论这个问题
听起来好像你在自己的工作,这使得同行评审困难。 我在一家Scrum商店工作。 部分过程要求我们讨论所有的修正和function,然后在编写一行代码之前从其他工程师那里得到买断(协议)。 这与“测量两次,切一次”相同。 我们花费大约一半的时间进行研究和规划,这是值得的投资。
这听起来像你没有一个项目经理。
你需要从着名的橡皮鸭debugging窃取技术,并将其应用于项目pipe理。 假设橡皮鸭是代表主要客户的项目经理,并向其解释说,您需要花费X小时研究新技术或新架构。 现在假设橡皮鸭问你,如果你认为这些新function值得X * Y的客户的钱,其中Y是你的小时工资加上你的办公桌和福利的成本。 接下来,橡皮鸭会问你是否认为这个新function值得推迟X小时交货。
根据你的回答,坦诚地回答鸭子的问题,并继续进行发展。
可以肯定的是,你应该问鸭子他是否总是花费在Stack Overflow上。
只要你达到你的时间目标 – 尽可能地投资。 如果你不能达到你的时间目标…只有当你认为满足要求是至关重要的时候,或者如果你认为你的方向是不可能的,那么以后如果错误的话就不可能解决。
过早的优化和处理,如果肯定会成为一个问题。
一个普遍的想法是确保你有尽可能好的代码,并且愿意在你学习的时候采用更好的实践。
总的来说,解决当前已知问题的最简单的答案通常是最好的。 然而,你的代码应该能够捕捉到意想不到的错误情况,并且logging/公开它们以增加对这些情况的更健壮的处理。
我经常遇到这种情况。 如果我需要用一种我经常使用的语言来解决某些问题,而这些语言如今已经是JavaScript,而且我被困住了,我还是试着用一个新的框架来解决这个问题。 有一些关于使用新工具,一个新的代码库,甚至是一个我通常不会用到的浏览器的东西,这可以帮助我摆脱尝试做正确的心理障碍。
旨在解决这一问题的关键是集中处理来自统一过程最关键特征的增量交付成果。 这需要执行纪律。
列出一些function(用例),对它们进行优先级sorting,select最高优先级,并将其作为您唯一需要的function。 以工作forms交付时,再次分析并select下一个要处理的function。
- select适合你的解决scheme,除非你受到当前的限制,否则不要去寻找别的东西(墨菲:如果没有被破坏,不要修复它)
- 创build一个优先列表并坚持下去。
另一种方法是定期检查你所做的所有事情,并将其重构为骨骼:删除所有不需要的东西。 根据需要重复。 使代码精简到下一个迭代。
问候
我通过试图平衡花费在调查和devise上的时间和我可以合理预期的使用和使用时间来避免过度或不足的工程。
假设我正在写一个只有我将会使用的实用程序,而且我将很less使用它,甚至只使用一次。 如果我可以select在Bourne shell或Perl中编写这样一个实用程序,在十分钟内运行一整夜,然后花费三个小时在C ++中使用复杂和困难的algorithm编写优化版本,比我的时间便宜。
另一方面,我写了多年来一直使用或影响数百万人的产品的关键组件。 在这种情况下,花费大量时间和精力花费在调查,研究和devise上,使用绝对最好的工具和技术,然后将所得到的代码打磨成光亮的效果是值得的。
没有一个全面的方法来做到这一点 – 这都是判断力。 正如所有的判断事情一样,经验是非常有帮助的,正如Aaron Digulla所指出的那样。
当我二十四年前从事专业软件开发人员时,我并不知道如何做出这些决定。 我只是写代码,如果它太慢或太多的东西,我会回去修复它。 但是当我做了这个修复的时候,我会试着想一下如何避免这个问题,以及我将来如何应用这个问题。 我也试图听其他程序员谈论他们碰到的问题,以及他们如何解决问题。
现在,很多项目,也许是数百万行代码,还有很多devise决策,我可以做出几乎本能的。 例如:“如果你在C ++中工作,而且你正面临着一些STL模板将要解决的问题,并且你不能避免使用STL,那么这就是要走的路,因为现代的STL实现是高度优化,而且从编写自己的代码中获得的任何改进都是不值得的。“
另外,我可以看一下情况,并说:“我们可能遇到问题的10%的项目在这里,在这里,在这里,所以我们需要集中研究和devise工作。另外90%,我们只是让它工作,但我们可以做到。“ 它运作得非常好。
因此,请保持编码,并不断改进您的代码,并不断从其他软件开发人员和您自己的经验中学习。 如果你继续关注和思考事物,那么随着时间的推移,提高软件devise的掌握将会随之而来。
时间拳击是我们做的。
我们有3天的时间来看看即将到来的问题,并尝试一些事情,并select一个解决scheme。
之后,运行它,并提前和经常提交,当你已经显示出一些进展,那么你可以重构,如果有更好的答案出现。
我发现防止过度工程的最好方法是确保只按照当前所知的方式编写代码。 如果你有一个类需要调用一个Web服务,并检索一种types的数据,不要写一些令人难以置信的强大的系统,可以处理每一个可能的情况。
也就是说,这种技术真的需要你创build干净,写得很好,易于理解的代码,并且要求你在任何地方都使用访问器。 如果你不这样做,你将会面临一场重构的噩梦。
当你编写代码时,只需要知道你所需要的知识就可以快速完成构buildfunction,当需求发生变化时,你可以返回并重构代码来添加缺失的function。 每当你添加一个新的function,你的代码将(阅读:应该)越来越好。
在项目开始的时候,肯定有一些总体的devise决定,但是这些决定是非常高的,不应该影响你按照需求改变的能力。
在使用这种技术的时候,你需要花点时间写一些新的模块来问自己当前实现是否需要它,如果不是的话,留下自己的评论,只写需要的东西。
有一个可靠的原则可以遵循:先把事情做好,然后聪明起来。 你必须达到第一个目标,第二个目标不要。
避免过度工程并不难,你只需要务实。
- 获取用户故事
- 从用户故事中提出用例
- 为第一个用例的第一个特性写一个unit testing
- 实现该function
- 必要时重构,使用SRP来分割太大的类
- 转到下一个function
- 继续下一个用例
- 完成之后,可以将API(例如REST)和数据库(例如PgSQL)添加到您的应用程序中(这部分取决于您遵循的开发模式)
通过使用TDD,您不必计划完整的类层次结构或了解整个项目,只需编写一小段代码或一次testing即可。 这只会把注意力集中在你真正需要的东西上
我目前正在试验干净的架构 ,这是非常有效的与TDD通过构build简单的可testing,可开发和可维护的应用程序。