Questions tagged «refactoring»

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

6
使用TDD时如何删除功能或功能
在有关TDD的文章中,我经常在重构步骤中读到“删除重复项”或“提高可读性”。但是,什么使我删除了未使用的功能? 例如,假设有一个C带有方法a()和的类b()。现在我认为有一个f()被驱动的方法会很不错C。实际上,除定义/描述的单元测试外,f()所有对的调用都将替换。不再需要-测试除外。b()b() 删除b()和使用它的所有测试是否保存?那是“提高可读性”的一部分吗?

3
TDD和重构遇到的困难(或者-为什么这比应该的要痛苦得多?)
我想教自己使用TDD方法,而我有一个项目想要工作一段时间。这不是一个大项目,所以我认为这将是TDD的不错的选择。但是,我感觉有些不对劲。让我举个例子: 在较高级别上,我的项目是Microsoft OneNote的加载项,它使我可以更轻松地跟踪和管理项目。现在,如果我决定建立自己的自定义存储和后端的一天,我还希望保持与OneNote分离的业务逻辑。 首先,我从一个基本的普通单词接受测试开始,概述了我希望我的第一个功能要做的事情。看起来像这样(为简洁起见,将其复制): 用户点击创建项目 用户输入项目标题 验证项目创建正确 跳过UI内容和一些中介计划,我来进行第一次单元测试: [TestMethod] public void CreateProject_BasicParameters_ProjectIsValid() { var testController = new Controller(); Project newProject = testController(A.Dummy<String>()); Assert.IsNotNull(newProject); } 到目前为止,一切都很好。红色,绿色,重构等。现在它实际上需要保存内容。在这里减少一些步骤,我对此很满意。 [TestMethod] public void CreateProject_BasicParameters_ProjectMatchesExpected() { var fakeDataStore = A.Fake<IDataStore>(); var testController = new Controller(fakeDataStore); String expectedTitle = fixture.Create<String>("Title"); Project newProject = testController(expectedTitle); Assert.AreEqual(expectedTitle, newProject.Title); } …

8
开发时与同事打交道,需要建议[关闭]
很难说出这里的要求。这个问题是模棱两可,含糊,不完整,过于宽泛或夸张的,不能以当前的形式合理地回答。如需帮助澄清此问题以便可以重新打开, 请访问帮助中心。 8年前关闭。 此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 8年前。 我开发了当前的项目架构,并开始自行开发(达到revision 40)。 我们正在开发一个简单的地铁路线框架,我的设计似乎做得非常好- 几个主要模型,相应的视图,主要逻辑和数据结构均按“应有的方式”建模,并且与渲染完全分离,并且还实现了算法部分除了主要模型之外,交叉点数量很少。 我将这种设计称为可扩展,可定制,易于实现的设计,它主要基于“黑匣子交互”进行交互,而且很好。 现在,完成了什么: 我开始了相应接口的一些实现,移植了一些方便的库,并为一些应用程序部分编写了实现存根。 我有描述编码风格的文档以及该编码风格用法的示例(我自己的书面代码)。 我强迫使用或多或少的现代C++开发技术,包括no-delete代码(通过智能指针包装)等。 我记录了具体接口实现的目的以及应如何使用它们。 单元测试(大多数情况下是集成测试,因为没有很多“实际”代码)和所有核心抽象的一组模拟。 我缺席了12天。 我们现在拥有什么(该项目是由团队的其他4位成员开发的): 3个不同的编码风格遍布项目(我猜,他们两个人同意使用相同的样式:),同样适用于我们的抽象的命名(例如CommonPathData.h,SubwaySchemeStructures.h),它们基本上头宣布了一些数据结构。 绝对缺乏有关最近实施的零件的文档。 我最近称之为“ single-purpose-abstraction现在”的事件至少可以处理2种不同类型的事件,与其他部分的关系紧密等等。 现在,一半的已使用接口包含成员变量(sic!)。 原始指针的用法几乎无处不在。 单元测试已禁用,因为“ (Rev.57) They are unnecessary for this project”。 ... (可能不是全部)。 提交历史记录表明,我的设计被认为是一种过大的技巧,人们开始将其与个人自行车和重新实现的车轮结合起来,然后在集成代码块时遇到了问题。 现在-该项目仍然只执行其少量工作,我们存在严重的集成问题,我假设有一些内存泄漏。 在这种情况下有什么办法可以做? 我确实意识到我的所有努力都没有任何好处,但是截止日期很快就到了,我们必须做些事情。有人有类似情况吗? 基本上,我认为为该项目做好一个良好的开端(好吧,我已尽力)可能会带来一些好处,但是,我知道我错了。


6
当其他人迅速提交代码库时,我该如何重构它?
我在一个私有项目中,该项目最终将成为开源项目。我们有一些团队成员,他们具有足够的技术来构建应用程序,但没有专门的开发人员来编写干净/美丽的代码,最重要的是长期可维护的代码。 我已经着手重构代码库,但这有点笨拙,因为与我不经常接触的另一个国家/地区的团队中的某人可能会更新此完全独立的内容。 我知道一种解决方案是快速沟通或采用更好的PM实践,但我们还不算大。我只想清理代码并将其很好地合并到他已更新的内容中。使用分支机构是否合适?尽力而为?还有吗

7
如果更改超过80%,是否应该在课程文件中更改作者姓名?
我正在重构现有的Java测试类集以进行自动UI测试。有时我最终会在类文件中进行大量更改或完全对其进行修改。这使我认为,当我重写整个课程时,是否应该在注释部分中更改作者姓名? 我在贪婪吗?还是让我看到我的名字并在有疑问的情况下问我会有用吗?

6
自我记录代码与Javadocs?
最近,我一直在努力重构当前正在处理的部分代码库-不仅可以自己更好地理解它,而且还可以使其他从事代码工作的人更容易理解。 我倾向于认为自记录代码很好。我只是认为它更干净,并且如果代码能说明一切,那 ... 很好。 另一方面,我们有诸如javadocs之类的文档。我也喜欢这个,但是这里的评论(当然还有一般的评论)也有过时的风险。但是,如果它们是最新的,那么理解复杂的算法就非常有用。 最佳做法是什么?您如何在自我说明代码和javadocs之间划清界限?

3
从整体式迁移到微服务时,如何处理外键约束?
我的团队正在从单一的ASP.NET应用程序迁移到.NET Core和Kubernetes。代码更改似乎正在进行中,并且可以预期,但是我的团队遇到的很多问题都围绕数据库进行。 当前,我们有一个相当大的SQL Server数据库,其中包含了整个业务的所有数据。我提议我们以与拆分代码类似的方式拆分数据库-一个逻辑数据库中的目录数据,另一个数据库中的库存数据,另一个数据库中的订单等-每个微服务都将成为其数据库的关守者。 这就意味着跨微服务边界的外键将必须被删除,跨边界的程序和视图将被禁止。所有数据模型可能会或可能不会驻留在同一个物理数据库中,但是即使它们存在,它们也不应直接相互交互。订单可能仍按ID引用目录项,但不会在数据库级别严格执行数据完整性,并且必须将数据以代码而不是SQL形式联接。 我认为这些损失是迁移到微服务并获得随之而来的可伸缩性优势时的必要折衷。只要我们明智地选择接缝并围绕它们发展,那应该没问题。其他团队成员坚持认为,所有内容都必须保留在同一个整体数据库中,以便所有内容都可以是ACID并在各处保留引用完整性。 这使我想到了我的问题。首先,我对外键约束和加入的立场是否合理?如果是这样,有人知道我可以提供给同事的任何可靠的阅读材料吗?他们的立场几乎是宗教性的,他们似乎不会因马丁·福勒本人告诉他们自己的错而受到任何影响。

7
如何证明代码重构时间?
有一个超过70k LOC的大型项目。 该项目肯定需要在Core Framework和其他部分中进行一些代码重构。在项目开始时没有设置任何时间进行重构。但是随着时间的推移,有40多个开发人员加入并离开了该项目。在我看来是必不可少的。 在争论和捍卫适当的软件开发原则时,您的重点是什么?

3
等待需求时对草率代码进行低影响的重构和代码清理
我继承了一个草率的产品的现有代码库。基本设计严重不足,不幸的是,如果没有完整的重构,我将无能为力(高耦合,低内聚,猖ramp的代码重复,没有技术设计文档,集成测试而不是单元测试)。该产品具有悠久的历史,对关键的“现金牛”客户敞口高,对风险的承受力最小,将使希腊人脸红的技术债务,非常庞大的代码库和复杂性,以及之前团队疲于奔命的错误解决方法我。 老团队跳船到另一个部门,以便他们有机会毁掉另一个项目。我很少遇到技术上无能力的项目失败,而不是项目管理失败,但这确实是其中一种。 就目前而言,我自己一个人,但我有很多时间,决定权和未来方向的自由,并且有能力从头开始建立团队来帮助我。 我的问题是,当您在功能需求收集阶段有一些空闲时间时,就对这样的项目的低影响重构收集意见。有成千上万的编译器警告,几乎所有警告都未使用的导入,未读的局部变量,没有类型检查和不安全的强制转换。代码格式是如此的难以理解和草率,以至于编码人员患有帕金森氏病,无法控制在任何给定行上按下空格键的次数。通常会打开其他数据库和文件资源,并且永远不会安全关闭它们。无意义的方法参数,执行相同操作的重复方法等。 在等待下一个功能的要求时,我一直在清理低冲击力,低风险的物品,并想知道自己是在浪费时间还是在做正确的事情。如果新功能意味着删除我之前花费时间的代码怎么办?我将开始一种敏捷方法,并且我知道这在敏捷开发过程中不断重构是可以接受和正常的。 您能想到我要添加的任何正面或负面影响吗?

8
还有其他人有重构问题吗?[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 看起来,在我编写了大量代码之后,我感到焦虑不安,好像我没有以最好的方式来完成它,而我最终却不断地在项目上重构和花费太多时间,或者从未得到过有时候做。这会发生在其他任何人身上吗?您如何处理呢?

6
枚举什么时候不是代码气味?
困境 我已经阅读了很多有关面向对象实践的最佳实践书籍,几乎我读过的每一本书都有一部分内容,他们说枚举是一种代码味道。我认为他们已经错过了解释枚举何时有效的部分。 因此,我正在寻找准则和/或用例,其中枚举不是代码的味道,而实际上是有效的构造。 资料来源: “根据经验,枚举是代码的味道,应将其重构为多态类。[8]” Seemann,Mark,依赖注入,.Net,2011年,第2页。342 [8] Martin Fowler等人,《重构:改进现有代码的设计》(纽约:Addison-Wesley,1999年),第82页。 语境 我陷入困境的原因是交易API。通过以下方法,他们给了我Tick数据流: void TickPrice(TickType tickType, double value) 哪里 enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... } 我尝试过围绕该API进行包装,因为打破更改是该API的生活方式。我想跟踪包装器上最后收到的刻度线类型的值,并且通过使用ticktypes字典来做到这一点: Dictionary<TickType,double> LastValues 在我看来,如果将它们用作键,这似乎是对枚举的正确使用。但是我有第二个想法,因为我确实有一个地方可以根据这个集合做出决定,而且我想不出一种消除消除switch语句的方法,我可以使用一个工厂,但是那个工厂仍然会有一个在某处切换语句。在我看来,我只是在移动东西,但仍然闻起来。 找到枚举的不容易,但是要做到的却不那么容易,如果人们可以分享他们的专业知识,利弊,我将不胜感激。 第二个想法 有些决定和行动是基于这些决定和行动的TickType,我似乎想不出消除枚举/切换语句的方法。我能想到的最干净的解决方案是使用工厂并返回基于的实现TickType。即使那样,我仍然会有一个switch语句,该语句返回接口的实现。 下面列出的是示例类之一,在其中我怀疑自己可能使用的枚举错误: public class ExecutionSimulator { Dictionary<TickType, double> LastReceived; void ProcessTick(TickType tickType, double value) { //Store Last Received …

5
如何避免过多的方法重载?
我们的应用程序源代码中有很多地方,其中一个类有许多具有相同名称和不同参数的方法。这些方法始终具有“上一个”方法的所有参数,再加上一个。 这是经过长期发展(遗留代码)和这种想法(我相信)的结果: “ 有一个方法M做A,我需要做A +B。好吧,我知道...我将向M添加一个新参数,为此创建一个新方法,将代码从M移到新方法使用一个以上的参数,在那儿执行A + B,然后使用新参数的默认值从M调用新方法。 ” 这是一个示例(类似于Java的语言): class DocumentHome { (...) public Document createDocument(String name) { // just calls another method with default value of its parameter return createDocument(name, -1); } public Document createDocument(String name, int minPagesCount) { // just calls another method with default value of its …

1
是否有理由等到第三规则中的第三次?
我刚刚在维基百科上看到了文章“ 三法则 ” 第三规则是代码重构的经验法则,用于确定何时应将新代码替换为新过程。它指出该代码只能复制一次,但是当同一代码使用3次时,应将其提取到新过程中。该规则由Martin Fowler在“重构”中引入,并归因于Don Roberts。 我知道这只是一个经验法则,但是为什么建议仅在第二次重复之后才进行重构?编写第一个副本时,重构有什么不利之处吗?

9
使用构造方法还是setter方法?
我正在编写具有Action类的UI代码,例如: public class MyAction extends Action { public MyAction() { setText("My Action Text"); setToolTip("My Action Tool tip"); setImage("Some Image"); } } 创建此Action类时,几乎可以假定Action该类是不可自定义的(从某种意义上说,它的文本,工具提示或图像在代码中的任何位置都不会更改)。现在,我们需要在代码中的某些位置更改动作文本。因此,我建议我的同事从构造函数中删除硬编码的操作文本,并接受它作为参数,以使每个人都被迫传递操作文本。类似于下面的代码- public class MyAction extends Action { public MyAction(String actionText) { setText(actionText); setTooltip("My Action tool tip"); setImage("My Image"); } } 但他认为,由于setText()方法属于基类,因此可以在创建操作实例的任何位置灵活地使用该方法传递操作文本。这样,无需更改现有的MyAction类。所以他的代码看起来像这样。 MyAction action = new MyAction(); //this creates action …

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.