由于主要需求变化很晚,目前正在对应用程序进行相当重大的重构。
我总是觉得,当我做这种事情时,我并没有以非常自律的方式接近它。我的应用程序很可能会在一个状态下每天/几周,它不会构建或需要注释掉大量的代码才能使其编译。
我不喜欢在这种状态下检查源代码控制,所以如果我犯了大错,我常常觉得我没有退缩。我现在正在摧毁我的应用程序,而且我正在控制着100个不同的主题。就像其中一个人,你读到的是出于好奇而将他们的汽车引擎分开的人,然后意识到他们不知道如何将它们全部重新组合在一起。
是否有任何好的资源可以讨论如何以更加渐进和破坏性更小的方式进行重构?有人可以提供任何建议吗?或者每个人都觉得这样吗?
答案 0 :(得分:18)
您所描述的事实上不重构。
重构是改进代码设计而不改变其功能的一项纪律性工作,以小 - 甚至简单 - 步骤完成,由单元测试保护,确保系统在每个步骤后正常运行。此外,它通常在较长的时间内以较小的增量进行,而不是在一个大的嗖嗖声中。
这不是过于热心,只是为了澄清这些术语:-)当我们以同样的方式理解相同的词时,误解和沟通问题的可能性就会降低。
当然,如果你有时间一次做很多重构,那就更好了!但是在你开始这样的努力之前,你绝对需要构建一套良好的单元测试,其中包括 - 理想情况下 - 你将要改变的代码部分中的所有功能。
由于您正在讨论“主要需求变更”,因此不清楚您所谓的“重构”是否实际上是在实现新功能,还是仅仅是改进设计以准备引入新功能。我强烈建议将这两个阶段分开:首先重构而不更改现有功能,以使您的设计对正确位置的扩展更加开放,这样您就可以更轻松地合并所需的功能更改
由@Eric链接的重构书是基本的;我想添加Josh Kerievsky的Refactoring to Patterns,这是关于重构的实际应用。
答案 1 :(得分:11)
你需要一个好的单元测试套件,以确保你不会破坏已经工作的东西。 Martin Fowler还有一本关于这个主题的好书:Refactoring: Improving the Design of Existing Code
我还建议抽象出你想要重构的代码部分,并且仍然为其他人提供旧的实现,同时你可以访问你正在编写的新代码,这样你仍然可以从源代码控制中受益。
使用分布式源代码控制系统还可以让您在不中断其他工作的情况下提交。
答案 2 :(得分:7)
使用允许本地分支的版本控制系统,例如git。这样,当您完成重构过程时,您可以继续在次要里程碑处登记。
答案 3 :(得分:5)
我正在解决类似的问题,这就是我所做的......
关键是保持每个重构步骤尽可能小和经常测试/提交。
答案 4 :(得分:2)
当您尝试使用未提交的更改实现多项操作时,您已经正式从“重构”转变为“黑客”。
您所做的每项更改都应具有目的,并且本身就是可测试的。当然,对于许多系统来说这是一个挑战,但不知何故,您需要验证给定一组输入,输出不会随着重构代码而改变。
答案 5 :(得分:1)
我知道这是语言无关的,但从.net的角度来看,我使用了一套好的单元测试,并使用Resharper来帮助完成这个过程。这个工具在我的重构努力中是非常宝贵的。
答案 6 :(得分:1)
正如您所发现的那样 - 一种无效或不存在的“设计”意味着后续的变化确实具有破坏性。
Upfront,在选择设计时,您必须尝试预测并考虑您将面临的可能变化。有些设计更好地接受更改 - 例如,如果您正在设计以适应快速波动的需求,那么使用自动生成的数据层,将验证保存在一个位置并保持GUI易于修改 - 这是应用程序中的一种规范化。如果您正在寻找速度可伸缩性等,那么您需要对代码进行非规范化并将验证放在多个位置,编写重叠层等。
因此,如果您后来发现自己正在破坏您的应用程序以进行必要的修复,请接受该设计无法解决并从中学习。
当您面对无效的设计时,这将花费您大量时间来进行预测更改,然后可以根据之前的回复中的描述重构设计。这可以在进行其他更改时完成,虽然理想情况下你会对你的老板说“嘿,我只是要重写这段代码几周,不,我不是要解决你真正想要的那些功能哦 - 是的我我也要编写一堆测试用例,但请不要解雇QA,因为它不是那种测试“。他会同意的!