由于一个小的规格更改结果证明没有正确指定规格,我丢掉了一项工作。如果它在项目开始时就完成了,那么一开始就不需要大部分工作。
有哪些好的技巧/设计原则可以防止这些事情发生?
或者减少为了实现功能请求或在实现过程中进行设计更改所需的代码返工量?
由于一个小的规格更改结果证明没有正确指定规格,我丢掉了一项工作。如果它在项目开始时就完成了,那么一开始就不需要大部分工作。
有哪些好的技巧/设计原则可以防止这些事情发生?
或者减少为了实现功能请求或在实现过程中进行设计更改所需的代码返工量?
模块化。制作能够很好地完成工作的小代码块。然而,这仅仅是开始。它通常是导致代码如此糟糕以至于需要彻底返工的因素的大量组合。从高度不稳定的需求、糟糕的设计、缺乏代码所有权,等等,不胜枚举。
添加到其他人提出的内容:沟通。
你和客户、你和管理层、你和其他开发人员、你和你的 QA 部门之间的沟通,每个人之间的沟通是关键。确保管理层了解合理的时间框架,并确保您和客户都准确了解您的建筑物是什么。
花时间与您构建产品的客户保持开放的沟通。制定里程碑并设置时间在每个里程碑向客户展示项目。即使客户在展示里程碑时对它完全失望,您也可以从头开始,从最后一个里程碑重新开始。正如 Csunwold 所说,这还要求您的工作构建在彼此独立工作的块中。
点...
正如已经说过的那样,模块化就是答案。但在实践中使用它可能是一个很难的答案。我建议重点关注:
首先编写接口是实现这两者的好方法(使用用于依赖项的接口)。接下来,在编写代码之前针对接口编写测试,通常会突出显示非模块化的设计选择。
我不知道你的应用是否是 UI 密集型的;这会使模块化变得更加困难。它通常仍然值得付出努力,但如果不是,那么假设它很快就会被丢弃并遵循冰山原则,即 90% 的工作与 UI 无关,因此更容易保持模块化。
最后,我推荐 andrew Hunt 和 dave thomas 的“实用程序员”,因为它充满了技巧。我个人最喜欢的是 DRY——“不要重复你自己”——任何说同一件事两次的代码都有味道。
软件需求发生变化,除了与客户更频繁的交互外,没有什么可以做的。
然而,人们可以构建在面对变化时更加健壮的代码。它不会使您免于丢弃满足不再需要的要求的代码,但可以减少此类更改的影响。
例如,只要适用,请使用接口而不是类(或您的语言中的等价物),并避免向接口添加操作,除非您绝对确定需要它们。通过以这种方式构建程序,您不太可能依赖特定实现的知识,并且您不太可能实现不需要的东西。
这种方法的另一个优点是您可以轻松地将一种实现换成另一种。例如,有时为您的原型编写最愚蠢的(效率上)但最快的编写和测试实现是有回报的,并且只有在原型是产品的基础并且实际上是性能时才用更智能的东西代替它很重要。我发现这是一种非常有效的方法来避免过早的优化,从而丢弃东西。
小迭代
经常迭代
迭代之间的测试
尽快得到一个简单的工作产品,以便客户可以提供输入。
基本上假设东西会被扔掉,所以适当地编码,并且不要深入到让它被扔掉的东西会花费很多时间。
天,
浏览此处的其他答案,我注意到每个人都在提到您的下一个项目要做什么。
不过,似乎缺少的一件事是进行清洗以找出规范的原因。不同步。以客户实际需求为准。
我只是担心,如果您不这样做,无论您采用何种方法来实施您的下一个项目,如果您仍然存在实际需求和规范之间的不匹配。对于您的下一个项目,您将再次处于相同的情况。
这可能是简单的沟通不畅或客户需求蔓延之类的事情。
但至少如果你知道原因并且你可以尝试帮助减少它再次发生的机会。
不要敲其他答案在说什么,那里有一些很棒的东西,但请从发生的事情中吸取教训,这样你就不会被谴责重复它。
高温高压
干杯,
有时重写是最好的解决方案!
如果您正在为相机编写软件,您可以假设下一个版本也将进行视频、立体视频或 3D 激光扫描,并包含所有这些功能的所有挂钩,或者您可以编写这样一个通用的可扩展宇航员架构,它可以应对包括喷气发动机在内的下一台相机——但它会在金钱、资源和性能上花费如此多的成本,你可能最好不这样做。
在新角色中完全重写新功能并不总是一个坏主意。
就像 csunwold 所说,模块化你的代码非常重要。编写它以便如果一个部分容易出错,它不会弄乱系统的其余部分。这样,您可以调试单个错误部分,同时能够安全地依赖其余部分。
除此之外,文档是关键。如果你的代码被整齐清晰的注释,那么在未来对你或任何碰巧正在调试的人来说,重新编写它将会变得无比容易。
使用源代码控制也很有帮助。如果您发现一段代码不能正常工作,总有机会恢复到过去的健壮迭代。
尽管它并不直接适用于您的示例,但在编写代码时,我会尽量留意我可以看到软件在未来发展的方式。
基本上,我试图预测软件将走向何方,但至关重要的是,我抵制实施任何我能想象到的事情的诱惑。我所追求的只是尝试让 API 和接口支持可能的未来而不实现这些功能,希望这些“可能的场景”能帮助我提出更好、更面向未来的接口。
当然并不总是有效。