Ways to prevent over-engineering?
在开发软件时,我通常会不断地问自己"这是最好的方法吗?""这项工作有更好的技术吗?"因此,我在实际调查和研究不同的设计模式/技术/最佳实践方面投入了更多的精力,而不仅仅是用我知道可以用的工具开发产品!
我通常会做的事情是想得太远,担心可能发生的事情,而不是专注于将要发生的事情。我不认为这一定是件坏事,但是,我发现有时候这会占用我太多的时间。
我想听听其他人是否也有类似的问题,以及他们如何着手解决这些问题?
截止日期。
采用XP的想法…雅格尼。(你不需要它)
足够的代码来解决现在需要做的事情。让你的客户满意,这才是最重要的。然后转到下一个功能。
如果你发现你需要重构某个东西,那么不管怎样,都要逐步地重构。
按这样的顺序。
是的,我见过和经历过很多次这个问题。(对我来说)第一个解决方案是时间表。不是通过在此处插入黑色魔术来确定的营销部门计划。我说的是你给自己或你的团队制定的月/季计划,你说"在这个日期,我们必须有一个可建设的、可工作的项目,如果他们那天取消了我们的项目,他们仍然会有好的东西。"
它所做的就是把你必须承诺的真正的里程碑摆在那里。记住,里程碑是石头。它们不动。同样地,日历也在滴答作响。如果你不能承诺及时提出一个足够好的解决方案,那你那天就没有什么值得的了。
就我个人而言,我认为三周的开发加上一周的集成、测试、清理和最终准备对于中小型团体来说是一个很好的安排。你的里程数会有所不同。
对。
要防止过度工程,请执行此操作。
构建解决问题的最小、最简单的东西。
调查替代方案。
好问题。以下是我发现的,这并不容易做到:
做原型。通过这种方式,我对这个问题的理解比我提前考虑它所能得到的要深,而且我从未将自己与次优代码结合在一起。
获得实际软件性能调整的经验,因为,至少在我的经验中,软件的过度工程会导致大量的性能问题,如本例所示。这将教会您什么是典型的设计方法同时导致复杂性和缓慢性,所以您可以避免它们。一个例子是过分强调类、数据结构和事件驱动样式的复杂性。(这与过早优化相反,通过尝试解决不存在的问题,最终会产生问题。)
有时,我对软件的简单性有一个非常不妥协的观点,而且对于除了我以外的所有人来说,这似乎是一个非常奇怪的代价。例如,我偶然发现了差分执行技术,它将UI代码缩短了一个数量级,并且使修改变得非常容易,但同时创建了一条学习曲线,这条曲线很少有人爬过。
根据我的经验,避免过度工程的最简单方法就是经验。尽管Greenhorns将无休止地与他们的疑虑和恐惧作斗争,但一位高级开发人员将做到这一点。他们会正确的(第二次,如果不是第一次的话)。
第二个最简单的方法是自信。然而,这里有一个危险:没有经验,自信是极其危险的。
剩下的问题是如何在短时间内同时到达。世界上最伟大的思想都在努力。我的路径是使用自动测试。这比任何事情都能更快地消除我的恐惧和疑虑。它允许我将知识和经验从我的大脑转移到计算机上,所以我可怜的小大脑可以自由地处理接下来发生的事情,我不必担心我已经解决的所有事情。
提前释放,经常释放
即使您不向外部客户发布,您仍然可以向产品所有者或测试人员发布内部版本。这种工作周期使您更加关注手头的任务,而不是未来。
练习雅格尼(你不需要它),你的生产力可能会提高。可能很多。
你可能想读管道胶带编程器,但是当你读的时候要运用好你的判断力。
测试驱动的开发和重构在一起意味着您不需要预先有最好的方法,甚至不需要看到所有细节是如何结合在一起的…是关于紧急设计的。
阅读这篇文章背后的想法可能会帮助你减少对完美主义的担忧:http://c2.com/cgi/wiki?应急设计
以下是我学习的方法:
- 首先学习编写一些简单的功能测试。
- 然后编写满足测试的代码。
- 寻找重复的元素或者可以简化的东西。在尝试简化/不复制代码之前,请确保所有测试都通过,这样您就有了重构的基线。
- 重构之后,再次运行所有测试——以确保您没有改变任何您关心的行为。
- 检查一下。
重复…直到完成…
当你和别人比时,这更容易做到…最好是已经知道怎么做XP的人。
- 过了一段时间,你学会了相信自己,并接受你不需要预先控制解决方案的所有细节…尽管首先开始研究风险/未知部分是值得的…
换句话说,学习xp;-)
雇佣一群软件架构师组成一个委员会来分析所有设计。
设计将以UML提交,以便于分析。
所有项目都将使用内部基于XML的语言,以避免单一语言的特殊性。
您还需要一个详细的编码标准,以避免工作人员过度设计东西。这应该只包括重要的事情,如的定位
这是一个与你的同龄人的审查应该有助于确定的事情。他们应该让你知道"你是不是在杂草丛中"(并且能够证明这一断言是正确的)。另一方面,他们也应该让你知道,如果你做得不够,并且正在设计一些脆弱的、没有足够弹性的东西来改变或解决问题。
使用部分CMMI;测量自己。
找出一种方法来记录你做了多少次工程和做了多少次工程。计算出在设计某些东西时平均要付出多少代价。等一两年再回头看。
多想一想它可能会在短期内帮助你,从长远来看,你将有数据来知道你对过度工程的恐惧是否合理。
型
有几种方法可以想到:
- 百万千克1把重点放在被问到的问题上,在可能的情况下尽可能清楚地提出要求。前者可能被视为对某些人的被动攻击,因为他们所要求做的并不一定是一种常见的做法。百万千克1百万千克1呆在当下,避免玩"假设"游戏,雅格尼。百万千克1百万千克1时间框的工作,使它不是一个黑洞吸纳所有的时间可用。百万千克1
型
还有一些需要注意的事情:
- 百万千克1不要因为做了你做的工作而自责。不管你做什么,过去都会停留在过去。百万千克1百万千克1应用程序的完美代码是一个神话。好计划的敌人是完美计划的梦想。百万千克1百万千克1虽然有些分析是好的,但要适度防止"分析瘫痪"。百万千克1
型
你需要两件事:时间拳击和同行评审
时间拳击就像说的一样简单——我将花N个小时研究技术,使其更好地工作。
同行评审意味着你与其他感兴趣的工程师讨论这个问题。
听起来好像你是在自己工作,这使得同行评审很困难。我在一家Scrum商店工作。这个过程的一部分要求我们讨论所有的修复和特性,然后在编写一行代码之前得到其他工程师的认可(同意)。这和"测量两次,削减一次"是一样的,我们花了大约一半的时间研究和规划,值得投资。
保持简单和直接
A maxim often invoked when discussing design to fend off creeping featurism and control complexity of development
http://en.wikipedia.org/wiki/kiss_原则
型
听起来你没有项目经理。
你需要从著名的橡皮鸭调试中吸取技术,并将其应用到项目管理中。假设橡皮鸭是你代表主要客户的项目经理,并向它解释你想花X个小时研究一项新技术或新架构。现在假设橡皮鸭问你是否认为新功能值得客户的钱的x*y,其中y是你的小时工资加上办公桌的费用和福利。接下来,橡皮鸭问你是否认为新功能值得推迟产品交付x小时。
诚实回答Duck的两个问题,并根据您的回答继续开发。
顺便说一句,你应该问问鸭子,他是否介意你花在堆栈溢出上的所有时间。
型
不难避免过度设计,你只要务实…
百万千克1获取用户故事百万千克1百万千克1从用户案例中创建用例百万千克1百万千克1为第一个用例的第一个特性编写单元测试百万千克1百万千克1实现该功能百万千克1百万千克1如果需要重构,请使用srp来拆分太大的类百万千克1百万千克1转到下一个功能百万千克1百万千克1转到下一个用例百万千克1百万千克1完成后,可以将API(例如REST)和数据库(例如PGSQL)添加到应用程序中(这部分取决于您遵循的开发模型)。百万千克1
通过使用TDD,您不必计划完整的类层次结构或了解整个项目,只需一次编写一小段代码或测试。这有很大的帮助,只关注你真正需要的东西…
我目前正在尝试使用干净的体系结构,通过构建易于测试、可开发和可维护的应用程序,这对于TDD非常有效。
另一种方法是定期检查您所做的一切,并将其重构为骨骼:删除不需要的所有内容。根据需要重复。使代码在下一次迭代中更精简。
当做
型
我通过尝试平衡我花费在调查和设计上的时间和我可以合理预期的使用时间和使用寿命来避免过度或不足的工程设计。
比如说,我正在编写一个只有我才会使用的实用程序,我很少使用它,甚至只使用一次。如果我可以在Burne shell或Perl中编码这样一个实用程序,在十分钟内运行一个晚上,然后用三小时编写一个优化版本,使用C++中复杂和困难的算法,在一分钟内运行…电比我的时间便宜。
另一方面,我写了许多年来被数百万人使用或影响的产品的关键组件。在这种情况下,花时间和精力进行大量的调查、研究和设计,使用绝对最好的工具和技术,然后将产生的代码打磨成光泽度是值得的。
要做到这一点,没有一成不变的方法——这都是判断。正如阿隆·迪古拉恰当地指出的那样,在所有的判断问题上,经验都是非常有帮助的。
24年前,当我以专业软件开发人员的身份开始工作时,我不知道杰克如何做出这些决定。我只会写代码,如果速度太慢或是太多问题,我会回去解决。但当我解决了这个问题后,我会考虑如何首先避免这个问题,以及如何在将来应用它。当其他程序员谈论他们遇到的问题以及如何解决问题时,我也试着倾听他们的意见。
现在,许多项目,也许数百万行代码之后,我几乎可以本能地做出许多设计决策。例如:"如果你在C++中工作,而你正面临一个STL模板将要解决的问题,并且你不被限制避免使用STL,那么这就是方法。这是因为现代的STL实现是高度优化的,而编写自己的代码所能得到的任何改进都不值得付出努力。"
另外,我可以看一个情况,然后说,"我们可能有问题的项目的10%在这里,这里,这里,所以这是我们需要集中我们的研究和设计工作的地方。另一个90%,让我们让它发挥作用,不管我们能做什么。"它的效果很好。
因此,继续编写代码,不断改进代码,不断向其他软件开发人员和您自己的经验学习。如果你继续关注和思考事情,随着时间的推移,提高软件设计的熟练程度会到来。
型
时间拳击就是我们要做的。
我们将对即将出现的问题进行为期3天的调查,并尝试一些解决方案。
在这之后,运行它并提前交付,并且经常交付,在您展示了一些进展之后,如果有更好的答案出现,那么您可以重构它。
为了解决这个问题,我们设计了以统一过程中最关键的特性为重点的增量交付的思想。执行纪律是需要的。
列出特性(用例),确定它们的优先级,选择最高的优先级,并像处理它是您唯一需要的特性一样处理它。以工作形式交付时,再次分析并选择下一个要处理的功能集。
我经常遇到这种情况。如果我需要用我经常使用的一种语言来解决某个问题,这就是今天的javascript,而且我被卡住了,我会尝试使用一个新的框架来解决这个问题。使用一个新的工具,一个新的代码库,甚至一个我通常不使用的浏览器,都有助于我克服尝试正确操作的心理障碍。
型
我发现防止过度工程的最好方法是确保您只为当前所知的大部分规范编写代码。如果您有一个类需要调用一个Web服务并检索一种类型的数据,那么就不必编写一个非常健壮的系统来处理所有可能的情况。
也就是说,这种技术确实要求您创建干净、编写良好、易于理解的代码,并且要求您在任何地方都使用访问器。如果你不这样做,你最终会做一个重构的噩梦。
当您编写的代码只满足您目前所知道的需求时,您将快速构建功能,当需求发生变化时,您可以返回并重构代码以添加缺少的功能。每次添加新功能时,代码都会越来越好。
当然,在项目开始时需要做出一些总体的设计决策,但是这些决策是非常高的级别,不应该影响您像需求那样进行更改的能力。
在使用这种技术时,您需要花一点时间,然后再编写任何新的模块来询问您自己当前的实现是否需要它,如果不需要,请给自己留下一个注释,只写需要的内容。
过早地优化和处理IFS肯定是个问题。
一个普遍的想法是确保你的代码尽你所能,并且愿意在你学习的时候采用更好的实践。
一般来说,解决当前已知问题的最简单答案通常是最好的。但是,您的代码应该能够捕获意外的错误情况,并记录/公开它们,以便您添加对这些角情况的更可靠的处理。
只要你达到你的时间目标-尽可能多地投资。如果你不能达到你的时间目标…只有当你认为满足需求是至关重要的,或者你认为你正在朝着一个错误的方向前进时,才进行投资。
型
有一个确定的原则要遵循:先把事情做好,然后聪明。你必须实现第一个目标,第二个你不能。
- 选择适合你的解决方案,除非你受到当前解决方案的限制,否则不要试图找到其他解决方案(墨菲:如果它没有被破坏,不要修复它)
- 创建一个优先事项列表并坚持下去。