你什么时候知道是时候重构/审查一些代码了?更好的是,你什么时候做?
可能像其他人一样,我发现自己知道某些事情需要重构/审查,但截止日期和管理没有时间去做。我还想听听您如何在一般开发过程中包含代码审查。
最近我发现自己在开发新功能/代码之前就这样做了。例如,如果我必须在应用程序的模块 X 中开发新内容或更改某些内容,我会对该模块进行代码审查。我发现它还可以帮助我更好地理解模块,这样我就可以更轻松地进行更改。
那么你什么时候知道是时候了,什么时候做呢?最重要的是,您如何将其纳入项目规划中?
你什么时候知道是时候重构/审查一些代码了?更好的是,你什么时候做?
可能像其他人一样,我发现自己知道某些事情需要重构/审查,但截止日期和管理没有时间去做。我还想听听您如何在一般开发过程中包含代码审查。
最近我发现自己在开发新功能/代码之前就这样做了。例如,如果我必须在应用程序的模块 X 中开发新内容或更改某些内容,我会对该模块进行代码审查。我发现它还可以帮助我更好地理解模块,这样我就可以更轻松地进行更改。
那么你什么时候知道是时候了,什么时候做呢?最重要的是,您如何将其纳入项目规划中?
重构不是我留出时间单独做的事情。当我开发新代码或维护旧代码时,我一直在这样做。将其融入您的日常工作中,并始终在代码中寻找可以改进的地方。
为了回应您在自己对这个问题的回答中添加的具体案例:我认为您的情况是一个很好的例子,说明什么时候重构而不是完全重写是个好主意。在更改一行代码之前,请确保为有问题的代码编写了一组好的测试用例。如果代码未通过某些测试,它将用于三个目的。首先,它会给你特定的领域来集中你的努力。其次,它将为您(向您的老板)提供编写代码的可靠理由。第三是您希望在重构代码时使用的标准单元测试安全网。
标准的 TDD 方式是 Red-Green-Refactor:做一个失败的测试,编写代码以通过测试,然后在仍然通过测试的同时重构现有代码。重构发生在测试通过之后,当你发现代码太复杂或使用了错误的模式时。重构应该是您日常开发过程的一部分,而不是开发周期结束时的附加组件。我认为,将重构保持在较小的范围内效果会更好。将其作为日常活动的一部分来防止糟糕的代码在重构发生之前变得太大——至少理想情况下是这样。
我倾向于看到“代码气味”,就像我一遍又一遍地重复相同的代码,或者我看到一些让我思考的东西,“必须有更好的方法来做到这一点,我会去寻找它。” 这是我编写代码的一部分,我认为拥有好的代码可能需要更长的时间才能完成,但它更容易扩展、可维护,或者让其他人接受它而不必花钱,这在某种程度上是一件好事几天弄清楚我在代码中做了什么。
如果您正在继承代码,那么我倾向于认为有两种关于如何处理它的思想流派:
1)保持距离。您可以在此处进行必要的更改以获取该功能并且不再执行此操作。如果您知道该模块将很快被替换,或者您每年只在此工作一次或两次,那么我可以看到不想花大量时间修复它的逻辑。
2)让自己沉浸其中并立即修复它。如果您所做的是相当广泛的更改或者是您将定期使用的一段代码,那么它可能被视为进行一些重构或文档的维护的一部分,或者您想描述哪里有错误的代码变成了不那么糟糕的代码,因为这将在以后节省您的时间。
重构是我在开发过程中不断做的事情,而不是我计划的事情。每当代码表明它可以以某种方式更好地结构化时,我都会进行适当的更改。
你永远不能期望得到完全正确的设计。实际的细微差别在实现过程中显露出来,通过不断重构,您始终努力获得更好的设计和分解代码。
我认为正确的答案是:总是!在开发新功能时,如果我看到一段可以重构的代码,我就去做。因为我使用 TDD,所以我不担心旧功能会停止工作。
当你的代码有异味时
除非我知道我将要复制代码,否则我通常不会这样做。因此,在编写新功能时,如果我发现自己说“嗯,我在其他地方做过类似的事情......”我会尝试看看如何重构原始功能以实现尽可能多的代码重用。
我一边进行重构,一边尝试保持快速和安全 - 代码区域测试得越好,我可以快速安全地完成更多工作。
此外,我标记了我认为需要进行更大检查的领域或架构问题,并尝试单独安排这些更大的会话——通常,使它们变得更大的原因是缺乏测试,这意味着我必须花一些时间来添加我需要的那些测试.
解决一个具体问题:有一个项目在几个月内编写了一些糟糕的代码(甚至是由不再在公司工作的人编写的)。完全重写是不可行的,我无法向客户或管理层解释。
所以我想知道在这种情况下是否可以接受在对该模块进行更改之前重构某个模块。
我知道这不是最好的情况,但上下文是一种特殊情况(代码已经损坏,无法全部重写)。
我会说我也在寻找代码气味,但我想更具体一些。我正在使用我的设计框架,该框架随着每个项目的发展而不断发展。我将倾向于在项目的早期进行大量重构和重新设计(训练自己将这些分开是我仍在努力的事情),随着我接近截止日期并接近解决任何问题或代码异味,我会放松并专注于我的具体实现。当我这样做时,我通常会发现(或创造)更多的东西,虽然功能性,但我并不完全满意。我将记录这些,并在我的下一次迭代项目中解决这些问题。
当我回到代码时,有时我会发现有一种更优雅的方式来处理这种情况,并为自己没有早点看到它而自责。有时,我会发现有更好的方法,但这不是我最初设想的方式。有时我发现它的方式很好,而改变它会过度设计。其他时候,我发现在修复其他问题时,我原来的问题已经消失了。
当我准备对代码进行功能性更改(功能、错误修复、性能等)时,我首先会问自己,如果代码具有理想的结构以进行更改,它会是什么样子。
然后我朝着那个方向重构
我现在进行功能更改。
最后,我再次重构以清理我的更改带来的丑陋。
我总是想平衡我的重构工作与其他因素(截止日期、这段代码的重要性、测试覆盖率等)。
如果您不需要更改该代码(它可以工作,无需扩展它),请不要这样做。随它去。换句话说,如果它需要更改,请编写一些测试重构它并包含您的更改。
我认为自己是一名新手程序员(目前我一直以编程为生仅 6 个月)并且我注意到,只要查看代码,您就应该感觉到它是否需要重构。
据我了解,有些人将此称为“代码气味”,但我会说这更像是一种不公平的感觉,即您没有尽自己最大的努力来处理您正在关注的代码。您可能不确定该做什么或如何改进代码,但如果您对代码不完美有一点怀疑,那么它很可能不是。
您通常可以使范围比模块更小。有时单个函数显然是单独重构的候选者,即使它只是重命名局部变量,通过使代码自我解释来消除对注释的需求,诸如此类。
如果您可以确定需要更改的区域,请在进行更改之前和期间清理该区域。我经常发现我需要执行一些重构才能对代码有足够的理解才能进行更改。
不过,我会向其他所有说要围绕代码进行某种测试的人添加我的声音。尝试至少涵盖一组合理的“正常”案例并实现一些自动化(几乎每种语言都有可用的框架),以便在每次小的更改后轻松快速地运行测试。当我第一次开始我的代码清理活动时,我希望我能想到/知道测试框架......
如果我在修复错误时一遍又一遍地访问相同的代码,我认为是时候重构它了。如果我加入了一个新项目或负责新代码,我也会坐下来开始重构。如果我要扩展某些东西,那么在进行任何重大更改之前,我会首先重构所有旧问题(在它们变得过于根深蒂固之前)。
当您达到某个目标标准化水平时,您就完成了重构。如果只是一般清理:1,2 或 3 就足够了。如果您要扩展代码,那么 4 或 5 会更好。如果你真的想在很长一段时间内利用现有的工作,那么 6 是要走的路。
保罗。
只回答你的部分问题:我会在这里重申其他一些人已经提出的观点 - 一般来说,如果你没有一组可重复的测试,你可以运行以确保你所做的改变没有' t破坏了代码-那么您可能根本不应该重构。
你说代码已经坏了。您可能会倾向于最初对其进行尽可能少的小改动,以使其“正常工作”。问题是,没有测试,你怎么能说它真的“工作”?
祝你好运!