Questions tagged «refactoring»

重构是一种用于重组现有代码主体,在不更改其外部行为的情况下更改其内部结构的有纪律的技术。

16
我的老板要求我停止编写小的函数,并在同一循环中完成所有操作
我已经读过罗伯特·C·马丁(Robert C. Martin)的一本名为《清洁代码》的书。在本书中,我看到了许多清理代码的方法,例如编写小的函数,仔细选择名称等。这似乎是迄今为止我所读过的最有趣的有关干净代码的书。但是,今天我的老板不喜欢我看完本书后写代码的方式。 他的论据是 编写小函数很痛苦,因为它迫使您进入每个小函数以查看代码在做什么。 即使主循环超过300行,也可以将所有内容放入主大循环中,以使其读取速度更快。 仅在必须复制代码时编写小型函数。 不要使用注释名称编写函数,而是将复杂的代码行(3-4行)放在注释上方;同样,您可以直接修改失败的代码 这与我读过的所有内容背道而驰。您通常如何编写代码?一个主要的大循环,没有小的功能? 我使用的语言主要是Javascript。由于我删除了所有小的明确命名的函数并将所有内容放入一个大循环中,因此我现在真的很难阅读。但是,我的老板喜欢这种方式。 一个例子是: // The way I would write it if (isApplicationInProduction(headers)) { phoneNumber = headers.resourceId; } else { phoneNumber = DEV_PHONE_NUMBER; } function isApplicationInProduction(headers) { return _.has(headers, 'resourceId'); } // The way he would write it // Take the right resourceId …

21
我的代码大部分都存在主要的设计缺陷。完成还是现在修复?[关闭]
我是一名高中生,和我的一个朋友一起从事C#项目,他的技能与我差不多。到目前为止,我们已经在100次提交中编写了大约3,000行代码和250行测试代码。由于学校的原因,我推迟了几个月的项目,最近我又可以将其重新备份。 备份时,我了解到我编写的代码设计不良,例如在渲染器中包含过多线程,在模拟CPU,GPU和游戏卡带之间的交互中无法很好地防止竞争情况,以及仅仅是多余和令人困惑的代码。 问题是我什至没有完成程序的主要功能,所以我无法真正重构,因此我不鼓励继续完全意识到我的代码设计有缺陷。同时,我不想放弃该项目。已经取得了很大的进步,工作绝不能浪费。 我似乎有两种选择:通过解决不良的设计来简单地完成功能,然后在一切正常进行后进行重构,暂停一切并在完成其余功能之前努力解决一切,开始项目到处都是新鲜的东西,或者由于项目过大(基本上是“回到绘图板”)而彻底放弃该项目。 根据他人在此类项目中的经验,如何使自己重回正轨?根据该站点上的答案,普遍的共识是,通常不需要重写,但是如果不能在不付出过多成本的情况下维护代码,则可以使用重写。我确实很想继续这个项目,但是就目前而言,我的代码设计得不够好,无法继续进行下去,而沮丧的情绪使我无法继续进行下去。

9
为什么要使用工厂类而不是直接对象构造?
我已经在GitHub和CodePlex上看到了几个С#和Java类库项目的历史,并且看到了切换到工厂类而不是直接对象实例化的趋势。 为什么要广泛使用工厂类?我有一个很好的库,通过老式的方式创建对象-通过调用类的公共构造函数。在最后的提交中,作者迅速将所有数千个类的公共构造函数更改为内部构造,并且还创建了一个具有数千个CreateXXX静态方法的巨大工厂类,这些静态方法通过调用类的内部构造函数来返回新对象。外部项目API损坏了,做得很好。 为什么这样的更改有用?用这种方式重构的目的是什么?用静态工厂方法调用替换对公共类构造函数的调用有什么好处? 什么时候应该使用公共构造函数,什么时候应该使用工厂?

13
我应该重构标记为“请勿更改”的代码吗?
我正在处理一个相当大的代码库,并且给了我几个月时间来重构现有代码。需要进行重构过程,因为很快我们将需要在产品中添加许多新功能,而就目前而言,我们将无法在不破坏其他功能的情况下添加任何功能。简而言之:我们许多人在他们的职业生涯中都看到过的凌乱,庞大,错误的代码。 在重构过程中,我有时会遇到类,方法或代码行,它们的注释如下: 设置了超时时间,以便给模块A一些时间做事。如果未按时计时,它将损坏。 要么 请勿更改。相信我,你会破裂的。 要么 我知道使用setTimeout不是一个好习惯,但是在这种情况下,我不得不使用它 我的问题是:遇到作者的此类警告时,我应该重构代码吗(不,我无法与作者联系)?


16
我应该删除未引用的代码吗?
我正在研究中等大小(10万行)的代码库,它们都是相对较新的代码(不到一年),并且具有良好的单元测试覆盖率。 我不断遇到的方法要么不再在任何地方使用,要么仅在仅测试特定方法的单元测试中引用。 如果确定不再需要此代码,是否应该删除它? 删除它的原因: 更少的代码,更少的错误 更少的代码更易于他人消化 它仍在源代码控制下 保留它的原因: 可以作为参考 有时可能有用 它可能被编写为“完善”类的功能

12
是否比实例变量更喜欢局部变量?
我正在使用的代码库经常使用实例变量在各种简单方法之间共享数据。最初的开发人员坚持认为这要遵循Bob / Robert Martin叔叔在Clean Code书中所述的最佳实践:“功能的第一个规则是它们应该很小。” 和“函数的理想参数个数为零(尼拉度)。(...)参数很难。它们需要很大的概念力。” 一个例子: public class SomeBusinessProcess { @Inject private Router router; @Inject private ServiceClient serviceClient; @Inject private CryptoService cryptoService; private byte[] encodedData; private EncryptionInfo encryptionInfo; private EncryptedObject payloadOfResponse; private URI destinationURI; public EncryptedResponse process(EncryptedRequest encryptedRequest) { checkNotNull(encryptedRequest); getEncodedData(encryptedRequest); getEncryptionInfo(); getDestinationURI(); passRequestToServiceClient(); return cryptoService.encryptResponse(payloadOfResponse); } private void …
109 java  refactoring 

15
TDD红绿色重构以及是否/如何测试变为私有的方法
据我了解,大多数人似乎都同意不应直接测试私有方法,而应通过任何公共方法对其进行测试。我可以理解他们的观点,但是当我尝试遵循“ TDD的三个定律”并使用“红色-绿色-重构”循环时,我对此有一些疑问。我认为最好用一个例子来解释: 现在,我需要一个程序,该程序可以读取文件(包含制表符分隔的数据)并过滤掉包含非数值数据的所有列。我想可能已经有一些简单的工具可以做到这一点,但是我决定从头开始实现它,主要是因为我认为这对我来说是一个不错的,干净的项目,可以进行TDD的实践。 因此,首先,我“戴上红色帽子”,也就是说,我需要测试失败。我想,我需要一种可以找到一行中所有非数字字段的方法。因此,我编写了一个简单的测试,当然它无法立即编译,因此我开始编写函数本身,并且在来回循环(红色/绿色)之后,我有了一个有效的函数和一个完整的测试。 接下来,我继续使用函数“ gatherNonNumericColumns”,一次读取文件,并在每一行调用我的“ findNonNumericFields”功能以收集最终必须删除的所有列。几个红绿色循环,我完成了,又一次具有工作功能和完整的测试。 现在,我认为我应该重构。由于我的方法“ findNonNumericFields”仅是因为我认为实现“ gatherNonNumericColumns”时需要它而设计的,所以在我看来,让“ findNonNumericFields”成为私有是合理的。但是,这将中断我的第一个测试,因为他们将无法再访问他们正在测试的方法。 因此,我最终得到了一个私有方法,以及一组测试它的测试。既然有很多人建议不要测试私有方法,那感觉就像我在这里陷入困境。但是我到底在哪里失败了? 我认为我本可以从更高的级别开始,编写一个测试以测试最终将成为我的公共方法的方法(即findAndFilterOutAllNonNumericalColumns),但这感觉与TDD的整个观点有些矛盾(至少根据Bob叔叔的说法) :您应该在编写测试和生产代码之间不断切换,并且在任何时间点,所有测试都在最后一分钟左右进行。因为如果我从为公共方法编写测试开始,那么在私有方法中获得所有详细信息之前,将需要几分钟(甚至几小时,甚至几天)才能使该方法测试公共方法通过。 那么该怎么办?TDD(具有快速的红绿色重构周期)是否与私有方法不兼容?还是我的设计有问题?

20
可以用可读代码替换优化代码吗?
有时,您会遇到必须扩展/改进某些现有代码的情况。您会看到旧代码非常精简,但是它也很难扩展,而且花时间阅读。 用现代代码代替它是一个好主意吗? 一段时间以前,我喜欢精益方法,但现在看来,最好牺牲很多优化,而采用更高的抽象,更好的接口和更易读,可扩展的代码。 编译器似乎也越来越好,因此诸如之类struct abc = {}的东西被悄无声息地变成了memsets,shared_ptrs产生的代码几乎与原始指针扭曲相同,模板工作得很好,因为它们产生了超精简代码,依此类推。 但是,有时您仍然会看到基于堆栈的数组和带有一些晦涩逻辑的旧C函数,通常它们不在关键路径上。 如果您必须以某种方式触摸其中的一小部分代码,那么更改这种代码是一个好主意吗?

11
严格出于测试目的修改代码是否是错误的做法
我与一名程序员同事讨论关于仅修改一段可工作的代码以使其可测试(例如通过单元测试)是好是坏的做法。 我的观点是,在保持良好的面向对象和软件工程实践的范围内(当然不要“公开一切”等),这是可以的。 我同事的观点是,仅出于测试目的修改代码(有效)是错误的。 只是一个简单的示例,请考虑某些组件(用C#编写)使用的这段代码: public void DoSomethingOnAllTypes() { var types = Assembly.GetExecutingAssembly().GetTypes(); foreach (var currentType in types) { // do something with this type (e.g: read it's attributes, process, etc). } } 我建议可以修改此代码以调出另一个可以完成实际工作的方法: public void DoSomething(Assembly asm) { // not relying on Assembly.GetExecutingAssembly() anymore... } 此方法接受一个Assembly对象进行处理,从而可以通过您自己的Assembly进行测试。我的同事认为这不是一个好习惯。 什么被认为是良好且常见的做法?

10
Java中每个类有多少行?[关闭]
根据您的经验,对于Java中的一个类来说,太多的代码行太多是什么有用的经验法则? 明确地说,我知道行数甚至不接近用于特定类中什么应该不使用的实际标准。应该根据适当的OOP原理(封装等)来设计类。就是说,经验法则可以为重构考虑提供一个有用的起点(例如,“嗯,此类有> n行代码;它可能不可读,并且在封装方面做得很差,所以我可能想看看是否应该在某个时候重构”)。 在另一方面,也许您遇到过非常大的类的示例,这些类仍然很好地遵守了OOP设计,并且尽管它们的长度很长,但是它们都是可读性和可维护性的? 这是一个有关每个函数行数的相关,不可重复的问题。

6
解决方法名称中的拼写错误
我在代码库中通常使用的一种方法是拼写错误(并且早于我)。 这不仅激怒了我,不仅因为它的拼写错误,而且更重要的是,这使我在第一次键入它时总是总是弄错名字(然后我必须记住“哦,对,应该把它拼写错了……”) 我正在对原始方法进行一些更改。我是否应该借此机会重命名怪胎法?

10
没有时间进行完整重构时,为遗留代码编写测试是否有意义?
我通常会尝试遵循《与Legacy Cod e 一起有效工作》一书的建议。我打破了依赖关系,将部分代码移到@VisibleForTesting public static方法和新类上,以使代码(或至少部分代码)可测试。并且我编写测试以确保在修改或添加新功能时我不会破坏任何东西。 一位同事说我不应该这样做。他的推理: 最初,原始代码可能无法正常工作。并且为它编写测试使将来的修复和修改变得更加困难,因为开发人员也必须理解和修改测试。 如果它是具有某些逻辑的GUI代码(例如〜12行,例如2-3 if / else块),则由于代码太琐碎而无法开始,因此测试不值得这样做。 类似的不良模式也可能存在于代码库的其他部分中(我还没有看到,我还很新)。一次大的重构就更容易清理它们了。提取逻辑可能会破坏这种未来的可能性。 如果我们没有时间进行完整的重构,是否应该避免提取可测试的部分并编写测试?我应该考虑这样做的不利之处吗?

7
当同事在未通知的情况下进行不必要的改进时,如何对我的代码负责?
我的队友之一是我们IT部门所有行业的杰作,我尊重他的见识。 但是,有时他会不加提示地查看我的代码(他是我们团队负责人的第二命令,所以可以预期)。因此有时他会在我完成最终目标并立即进行更改之前查看我的更改,甚至破坏了我的工作一次。 其他时候,他对我的3个月以上的代码进行了不必要的改进。 这让我很烦,原因有几个: 我并非总是有机会改正我的错误 当他感到困惑时,他没有花时间问我要做什么,这可能会影响他的测试或更改 我并不总是认为他的代码可读 截止日期不是问题,他的当前工作量除了查看我的代码更改外,不需要在我的项目中进行任何工作。 无论如何,我过去曾告诉过他,如果他在我的工作中看到一些他想更改的东西,以便我可以拥有我的代码(也许我应该说“缺点”),并且他没有回应,请把我保持在工作状态。 。 当我问他向我解释他的改变时,我担心我可能会变得冒犯别人。 他只是一个沉默寡言的人,坚持不懈,但他的行为仍在继续。我不想阻止他进行代码更改(不是像我能做到的那样),因为我们是一个团队,但是我想尽自己的一份力量来帮助我们的团队。 补充说明: 我们共享1个开发分支。我不会等到所有更改都完成一个任务后再做,因为我可能会失去一些重要的工作-因此,我确保我的更改可以建立并且不会破坏任何内容。 我担心的是,我的队友没有解释其更改背后的原因或目的。我认为他不需要我的祝福,但是如果我们不同意我的做法,我认为最好是在我们都了解发生了什么之后再讨论利弊并做出决定。 我尚未与团队负责人讨论此事,因为除非有必要,否则我宁愿在不让管理层介入的情况下解决个人分歧。由于我的担忧似乎更多是个人问题,而​​不是对我们工作的威胁,因此我选择不打扰团队领导。我正在研究代码审查过程的想法,以帮助促进组织更有组织性的代码审查的好处,而又不至于使我烦恼。

2
为我不明白目的的代码编写测试
我最近完成了黑盒重构。我无法检入它,因为我无法确定如何进行测试。 在较高的层次上,我有一个其初始化涉及从某些类B获取值的类。如果类B为“空”,它将生成一些合理的默认值。我将这一部分提取到一种方法中,该方法将B类初始化为相同的默认值。 我还没有弄清这两个类的目的/背景,或如何使用它们。因此,我无法从空的类B初始化对象并检查其是否具有正确的值/是否做正确的事情。 我最好的主意是运行原始代码,根据初始化的成员在公共方法的结果中进行硬编码,然后对此进行测试。我不太清楚为什么我对这个想法含糊不清。 这里有更好的进攻方式吗?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.