我继承了一个产品的现有代码库,这个代码库应该是草率的。基础设计严重不足,不幸的是,如果没有完整的重构(高耦合、低内聚、频繁的代码重复、没有技术设计文档、集成测试而不是单元测试),我几乎无能为力。该产品有着悠久的历史,与关键的“摇钱树”客户有很高的敞口,对风险的容忍度最低,技术债务会让希腊人脸红,代码库和复杂性都很大,我前面的团队对bug采取了一种厌倦战斗的失败主义方法。
老团队跳槽到另一个部门,以便他们有机会破坏另一个项目。与项目管理失败相比,我很少遇到技术不称职的项目失败,但这确实是其中之一。
就目前而言,我是一个人,但我有很多的时间,自由的决定和未来的方向,并有能力从零开始建立一个团队来帮助我。
当您在功能需求收集阶段有一些空闲时间时,我的问题是在这样的项目中收集对低影响重构的意见。有数以千计的编译器警告,几乎所有这些警告都是未使用的导入、未读取的局部变量、没有类型检查和不安全的转换。代码格式是如此不可读和草率,它看起来像受帕金森斯病的编码器,无法控制空格键在任何给定的线上按下的次数。进一步的数据库和文件资源通常是打开的,永远不会安全关闭。没有意义的方法参数,重复的方法,做同样的事情,等等。
当我在等待下一个功能的需求时,我一直在清理低影响、低风险的东西,我想知道我是在浪费时间还是在做正确的事情。如果新特性意味着撕掉我之前花时间编写的代码呢?我将开始一种敏捷方法,我理解在敏捷开发过程中不断重构是可以接受的,也是正常的。
你能想到我做这件事有什么积极或消极的影响吗?
发布于 2011-07-05 13:46:31
首先,我想指出,单元测试不是集成测试的替代品。这两者需要共存。感谢您进行了集成测试,否则您的一个小重构很可能会让一个低容忍度的经济母牛对您大发雷霆。
我将开始处理编译器警告和未使用的变量和导入。先弄个干净的建筑。然后开始编写单元测试来记录当前行为,然后开始真正的重构。
我看不出有什么负面影响。您将对代码基础有很多深入的了解,这将有助于进行更大的重构。几乎总是比重写更可取,因为在重构过程中,您仍然有一个工作产品,而在重写过程中,您没有。最后,产品的销售必须支付您的工资。
一旦需求开始出现,我就会使用我称之为聚光灯的方法。做通常的敏捷工作(优先排序,然后为迭代切断一个小块,并完成这个任务),并为代码改进留出相当多的时间。然后重构你正在工作的地方。随着时间的推移,这将涵盖代码库的广泛领域,而不必冒险进入您难以为管理代码的这一部分而进行管理的领域。
发布于 2011-07-05 13:38:20
编写单元测试可能会更有价值地利用您的时间:它将使您了解当前代码库的工作,并且如果您决定从您拥有的东西开始,而不是从头开始重写所有东西,那么您将有一个坚实的基础来进行更改,而不会冒太多的风险。在编写单元测试时,您可能还会对代码基进行更改,以使其成为可测试的形状;这是很好的,因为单元可测试性通常也意味着模块化、封装性和大部分独立于外部状态。而且,最重要的是,编写良好的单元测试是宝贵的技术文档。有了单元测试,您将能够判断当前的代码库可以做什么和不能做什么,而不是只为以防万一而胡思乱想或重写。
发布于 2011-07-05 14:07:56
混合答案-我的想法是混合测试和清理-也许50/50?如果您的工作区域正在执行TDD类型的方法--设置测试,您需要知道单元和集成测试是否符合要求,然后开始修复。在时间允许的情况下继续前进。
这可能意味着您不会取得那么大的进步,但这意味着您至少在某些领域将有一个非常稳定的代码库,并且您将有一个良好的启动基础。
我最初的反应是“清理被破坏的代码真的会伤人吗?”(也就是编译器错误),但我记得在一些非常奇怪的情况下,修复问题实际上破坏了功能,因为它没有让线程死掉,而是把内存留在了糟糕的地方--本质上是一个糟糕的中断掩盖了一个更糟糕的错误。它可以是潘多拉的盒子,充满了令人不快的惊喜。
考虑到您是在等待更多的需求时这样做的,我认为您可以诊断混乱的任何东西都会大大增加您的长期理智。
https://softwareengineering.stackexchange.com/questions/89741
复制相似问题