Questions tagged «refactoring»

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

3
您如何摆脱代码维护者的角色?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 在最近的三份工作中,我是代码维护者。在这三种情况下,我都已经为该项目编写了大部分代码后才被雇用。 我是一个自学成才的程序员。在开始我的第一份专业工作之前,我大概有十几个项目可以成功启动并交付。 编写新代码和维护现有代码是两个完全不同的工作。就像将航空工程师和飞机技师进行比较。 当您是由一名工程师设计的飞机机械师,而该工程师没有试图使飞机以任何逻辑或易于维护的方式设计时,这种情况尤其糟糕。 我开始感觉像在项目刚开始时就在身边,您必须是那些以某种方式超越了计算机科学领域其他人员的特殊人员之一。处于那个位置需要什么? 我觉得这个问题确实没有简单的答案,但是有人可以给我一些见解吗?您曾经在一个新项目的底层吗?到达那里需要什么?

3
有什么好的方法来组织输入文件(Makefiles,SConstruct,CMakeLists.txt等)以构建自动化软件?
我喜欢对我的代码做的一件事是确保将其重构为可管理的部分。但是,在构建软件时,我发现无论我最终使用的构建自动化软件(最近是GNU Make或SCons)最终都变得一团糟。输入文件看起来像长脚本,似乎不容易重构。我希望能够以某种方式对其进行重构,但是“功能”的概念在某些构建自动化软件中的行为与编程语言中的行为并不完全相同,因此我发现很难编写可管理的代码任何中等复杂项目的Makefile文件或SConscript文件。 在编写用于构建自动化软件的可管理输入文件方面,有任何建议吗?与软件无关的建议是最好的,但是即使是关于特定构建自动化工具的建议也将有所帮助,尤其是Make或SCons,因为这就是我在项目中一直使用的。 编辑:正如Thorbjørn所指出的,我应该添加一些上下文和用法示例。我正在完成化学工程博士学位,并从事计算科学方面的研究。(我是SciComp.SE上的一名程序员,对于那些访问的人来说。)我的项目通常涉及混合编译语言(C,C ++,Fortran),它们执行某些繁重的脚本语言(Python) ,Perl)用于原型制作,偶尔也可以使用特定领域的语言进行原型制作或技术用途。 我在下面添加了两个示例,大致在250行范围内。对我来说,问题通常是缺乏模块化。这些项目中的一些可以组织成模块化的单元,并且最好按照这些思路抽象出构建的各个部分,以使我和将来的维护者更容易跟踪。将每个脚本分解成多个文件一直是我脑子里一直在想的一个解决方案。 第二个示例特别重要,因为我很快将不得不处理大量文件。 这是一条265行Makefile对我来说的样子,取自一个实际项目,并尽我所能组织: #!/usr/bin/make #Directory containing DAEPACK library folder daepack_root = . library = $(daepack_root)/lib wrappers = $(daepack_root)/Wrappers/DSL48S c_headers = parser.h problemSizes.h f77_headers=problemSizes.f commonParam.f f90_headers=problemSizes.f commonParam.f90 includes = -I. -Iinclude -I/usr/include/glib-2.0 \ -I/usr/lib/glib-2.0/include -I/usr/include/libxml2 \ -I/usr/include/libgdome -I/usr/include/gtest/ #Fortran 77 environment variables f77=gfortran fflags=-ggdb -cpp …

7
您如何使用大型代码库和许多开发人员来管理重构?
我想避免出现这样的情况,即两个开发人员在不首先讨论它的情况下同时重构同一代码,可能是使用某种工具,也许是Eclipse插件。你能帮我吗? 我们拥有450万行代码,并在四大洲拥有20多个开发团队。 理想情况下,我希望前面提到的第二个开发人员注意到其他人正在处理同一段代码,并在修改任何内容之前先与第一个代码交谈。 您知道解决方案吗?

5
解决由于重构引起的合并冲突
最近,我参与了有关如何处理重构的讨论(这本身就是一个有趣的话题)。最终提出了以下问题: 一个人如何处理由于某人对一部分代码进行重构而其他人在为同一段代码开发功能时发生的合并冲突呢? 基本上,我不知道如何有效地处理这一问题。在这方面是否应遵循任何最佳做法?对于具有大量旧代码的系统,应该如何处理呢?

7
将压倒性代码分解为可管理块的最佳方法?
一旦大型项目达到一定程度的复杂性,我就会变得不知所措。一旦到达项目中的某个特定点,我的进度就会缓慢地爬行,并且发现自己不断地追踪自己的步骤并理清各种混乱。 由于我的这个弱点,我真的很擅长重构。而且我总是尝试将对象分解为更小,更易于管理的对象。这种弱点也可能导致我过多地注意正确设计事物。 我知道如果我可以将问题分解为较小的问题,那么我将能够顺利完成任务。想到的一种策略是测试驱动的开发。我还可以做些什么?

5
微型重构代码以提高质量是否有用,还是只是“移动代码”而没有太多好处?
例 我遇到了在一个地方完成所有工作的整体代码-从数据库加载数据,显示HTML标记,充当路由器/控制器/动作。我开始应用SRP将数据库代码移动到其自己的文件中,从而为事物提供了更好的命名,而且看起来都不错,但是随后我开始怀疑为什么要这样做。 为什么要重构?什么目的?它没用吗?有什么好处?请注意,我基本上保留了整体文件,但只重构了与需要进行某些工作的区域相关的较小部分。 原始代码: 举一个具体的例子,我遇到了以下代码片段-它通过已知的产品ID或用户选择的版本ID加载产品规格: if ($verid) $sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid); else $sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ; $result1 = query($sql1); $row1 = fetch_array($result1); /* html markup follows */ 重构: 由于我正在做一些工作,要求我在代码的此特定部分中进行更改,因此我将其更改为使用存储库模式,并将其升级为使用面向对象的MySQL工具: //some implementation details omitted …

4
表示依赖注入相反的技术术语?
这更多是术语(技术写作),而不是纯粹的技术问题。我正在尝试围绕我们的应用程序中扩展依赖项注入编写一个重构建议(并将其分配给我自己)。虽然我们确实使用Spring来自动装配Bean,但是仍然存在使用实例化Bean的实例,这些实例MyClass obj = new MyClass(...)可以完全注入。我想使我的建议使用优雅的命名法,并用适当的术语指代DI的设计模式。 “紧密耦合”是否足以作为DI的反义词?

7
编写代码后,为什么一段时间后我觉得“我会写得更好”?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我从事C ++的业余项目已有2年以上。每当我编写模块/函数时,我都会经过很多思考。现在看到问题了 do { --> write the code in module 'X' and test it --> ... forget for sometime ... --> revisit the same piece of code (due to some requirement) --> feel that "This isn't written nicely; could have been better" } while(true); 这'X'是任何模块(小/大/中)。我观察到,无论我在编码时付出了多少努力,这种情况都会发生。因此,大多数情况下,我不会看到有效的代码。:) 这是很多人的普遍感觉吗?这是语言的特定现象吗?(因为在C ++中,可以用不同的方式编写相同的东西)。 如果我对现实世界的生产代码有这种重构的感觉,该怎么办,在那儿更改工作代码不会赢得很多荣誉,但是如果失败,可能会带来麻烦。

7
重构和开放/封闭原则
我最近正在阅读一个有关干净代码开发的网站(我不在此处放置链接,因为它不是英语)。 本网站宣传的原则之一是开放式封闭原则:每个软件组件都应开放以进行扩展,而封闭则可以进行修改。例如,当我们实现并测试了一个类时,我们仅应对其进行修改以修复错误或添加新功能(例如,不影响现有方法的新方法)。现有功能和实现不应更改。 我通常通过定义接口I和相应的实现类来应用此原理A。当类A变得稳定(实现并经过测试)后,我通常不会对其进行过多修改(可能根本没有修改),即 如果新的要求到达需要的代码大的变化(如性能,还是一个全新的接口的实现),我写了一个新的实现B,并使用保持A,只要B还没有成熟。当B成熟时,所需要做的就是更改I实例化方式。 如果新的要求也建议更改接口,那么我将定义一个新的接口I'和一个新的实现A'。所以I,A被冻结并保持实施生产系统,只要I'和A'不够稳定,以取代他们。 因此,鉴于这些观察,令我感到惊讶的是该网页随后建议使用复杂的重构,“……因为不可能直接以其最终形式编写代码。” 在执行“开放/封闭原则”与建议使用复杂重构作为最佳实践之间是否存在矛盾/冲突?还是这里的想法是,在开发一个类的过程中可以使用复杂的重构A,但是当成功测试了该类后,应该冻结它吗?

2
将单元测试添加到旧的普通C项目中
标题说明了一切。我公司正在将微控制器设备的旧固件项目重复使用,完全用纯C语言编写。 有些部分显然是错误的,需要更改,并且这些部分来自C#/ TDD背景,我不喜欢无测试地随机重构内容以确保功能保持不变的想法。此外,我已经看到,在很多情况下,通过微小的更改就引入了难以发现的错误(如果使用回归测试,我相信这是可以解决的)。为避免这些错误,需要格外小心:很难在代码周围跟踪大量的全局变量。 总结一下: 在重构之前,如何在现有的紧密耦合代码中添加单元测试? 您推荐什么工具?(重要性不高,但仍然很高兴知道) 我没有直接参与编写此代码(我的责任是一个可以通过多种方式与设备交互的应用程序),但是如果有可能使用它们时,如果抛弃了良好的编程原则,那将是很糟糕的。

4
在单个敏捷工作项中处理“相关”工作
我是一个由4个开发人员组成的项目团队,其中包括我自己。我们一直在讨论如何处理单个工作项中出现的额外工作。 这些额外的工作通常是与任务稍有相关的事情,但并非总是必须达到项目目标(可能是一种观点)。示例包括但不限于: 重构工作项更改的代码 与项目更改的代码相邻的重构代码 重新设计票证周围较大的代码区域。例如,如果某个项目要更改单个功能,那么您意识到现在可以重做整个类以更好地适应此更改。 改进刚修改过的表单上的用户界面 当这笔额外的工作很少时,我们不在乎。问题是,当这项额外的工作导致项目的实质扩展超出了原始特征点估计时。有时,一个5分的物品实际上需要13个时间。在一种情况下,我们得到了13分,回想起来可能是80分或更高。 在我们的讨论中,有两种解决方案。 我们可以在同一个工作项中接受额外的工作,并将其记为错误估计。对此的论点包括: 我们计划在sprint末尾进行“填充”以解决此类问题。 始终使代码保持比发现的状态更好的形状。不要签入半途而废的工作。 如果我们将重构留给以后使用,则很难安排时间,并且可能永远无法完成。 您现在处于最佳的心理“环境”中来处理此工作,因为您已经在代码中深陷其中。最好是现在就解决它,并且比以后再丢失该上下文时更有效。 我们为当前工作项目划了一条线,并说额外的工作进入单独的工单。参数包括: 拥有单独的票证可以进行新的估算,因此我们不必对自己的真实情况撒谎,也不必承认我们所有的估算都是可怕的。 冲刺“填充”用于应对意想不到的技术挑战,这些挑战是完成票证要求的直接障碍。它不适用于仅“精打细算”的附带物品。 如果要安排重构,只需将其放在待办事项列表的顶部即可。 我们没有办法在估算中正确考虑这些内容,因为出现时似乎有些武断。代码检查者可能会说“那些UI控件(您实际上未在此工作项中对其进行修改)有些令人困惑,您也可以解决吗?” 这就像一个小时,但他们可能会说:“好吧,如果此控件现在与其他控件继承自相同的基类,为什么不将所有这些(几百行)代码都移到基类中并重新连接所有这些内容,级联的变化等?” 那需要一个星期。 它通过在票证中添加无关的工作来“污染犯罪现场”,从而使我们的原始特征点估计毫无意义。 在某些情况下,额外的工作会推迟检入,从而导致开发人员之间的阻塞。 我们中有些人现在说,我们应该决定一些截止日期,例如,如果其他物料少于2 FP,则将其放入同一票证中;如果更多,则将其设为新票证。 既然我们只需要几个月就可以使用敏捷,那么这里周围所有经验丰富的敏捷退伍军人对此有何看法?

4
在功能分支上工作时应提高代码质量吗
我真的很喜欢这篇文章,它使代码/营地处于比您发现的状态更好的状态 -在现实世界中,保持代码整洁似乎是一种实用的方法。 我也非常喜欢要素分支,它是一种独立开发要素的方法,这样,如果您不喜欢它,就可以轻松地将其合并等。 但是,如果我在功能分支上工作,并且发现一些难看的代码,是否应该解决它? 感觉有很多缺点需要解决: 当我将分支合并回去时,差异将变得混乱,变量重命名或函数提取会变得混乱 如果放弃了该功能,则必须选择清除提交(根据其附近的代码如何进行混乱的合并而改变可能有效或无效),重新执行或放弃它。 另一方面,如果我在文件中时不执行此操作,那么很明显,我会在合并分支的几天之内忘记执行此操作。 我被警告说这是基于观点的(我认为标题仅包含事实should),但是我觉得有一个答案(肯定有人使用这两种方法,所以他们必须有答案)。此外,有关的问题development methodologies都是话题,我认为它们需要一定的意见。

2
用重构注释扩展代码是一个好主意吗?
我正在研究“意大利面条代码”项目,并且在修复错误和实现新功能的同时,我还进行了一些重构,以使代码可以进行单元测试。 这些代码通常紧密耦合或非常复杂,以至于修复一个小错误将导致许多类被重写。因此,我决定在代码中停止重构的位置画一条线。为了清楚起见,我在解释这种情况的代码中添加了一些注释,例如: class RefactoredClass { private SingletonClass xyz; // I know SingletonClass is a Singleton, so I would not need to pass it here. // However, I would like to get rid of it in the future, so it is passed as a // parameter here to make this change …

5
代码重复与多负责任的方法
我尝试遵循“单一职责原则”(SRP),并且也省略代码重复。但是,通常在某些地方存在代码重复,这些代码重复不过是调用的代码块,这些代码块无法将其提取到至少有意义的命名方法中: DoAction1(); DoAction2(); if (value) DoAction3(); DoAction4(); 将此类代码提取到方法中的最佳方法是什么?如何命名?

5
为什么我的班级比本书中的班级等级(初学者OOP)更糟糕?
我正在阅读PHP对象,模式和实践。作者正试图在大学里模拟一堂课。目标是输出课程类型(讲座或研讨会),并且该课程的费用取决于它是每小时课程还是固定价格课程。所以输出应该是 Lesson charge 20. Charge type: hourly rate. Lesson type: seminar. Lesson charge 30. Charge type: fixed rate. Lesson type: lecture. 当输入如下时: $lessons[] = new Lesson('hourly rate', 4, 'seminar'); $lessons[] = new Lesson('fixed rate', null, 'lecture'); 我这样写: class Lesson { private $chargeType; private $duration; private $lessonType; public function __construct($chargeType, $duration, …

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.