为什么干很重要?


81

非常简单,当我需要做的就是重复几次相同的过程并做一些细微调整后,为什么还要编写适用于所有情况和可伸缩数据的代码?

我不太可能需要在不久的将来再次进行编辑。

看起来要减少很多工作...

function doStuff1(){/*.a.*/}
function doStuff2(){/*.b.*/}
function doStuff3(){/*.c.*/}

如果我需要添加一些内容...

function doStuff4(){/*.d.*/}

如果我需要将其删除,则可以将其删除。

很难弄清楚如何将所有这些都变成一个简单的模式,以便我可以将数据输入并处理所有情况,并进行很多我不希望拥有的更改去做。

当看起来像快速剪切+粘贴会减少工作量时,为什么要干呢?


11
因为如果正确地进行操作,干燥仍然会更快,如果您在操作中犯了一个错误,该怎么办。会影响所有其他人
Daniel Little

97
您可能希望,但我不太可能很快再进行编辑”,但很可能您在这里犯了一个错误。而且,如果您要再次处理该代码,但又不是很快,那只会使情况变得更糟。您会忘记重复项在哪里,重复项会变得细微但又背叛。引用经典的话说:“好像维护您代码的人是一个危险的狂人,知道您的住所。”
9000

14
我认为您可以总结一下:单点更改更易于维护。
猎鹰

17
如果您自己不能回答这个问题,则需要获得更多有关开发和维护的真实经验。
David Heffernan

15
@Wayne我从源头上感到极大的困扰,好像数百万程序员突然惊恐地大喊。
隐身

Answers:


121

如果您重复自己的话,则会造成可维护性问题。如果doStuff1-3都具有类似的结构化代码,而您在一处解决了一个问题,则很容易忘记在其他地方解决该问题。同样,如果您必须添加新的大小写来处理,则可以简单地将不同的参数传递给一个函数,而不必在各处复制粘贴。

但是,聪明的程序员经常将DRY发挥到极致。有时候,为了不重复自己,您必须创建抽象,以至于使您的队友无法遵循这些抽象。有时,两件事的结构只是模糊地相似,但又足够不同。如果doStuff1-4的差异足够大,以至于对其进行重构以免重复您自己,从而使您不得不编写不自然的代码或进行巧妙的编码后空翻,从而使您的团队目瞪口呆,那么重复一下自己就可以了。我向后弯下腰,不以不自然的方式重复几次,并对最终产品感到遗憾。

我总是错在DRY的一边,在极少数情况下,当我认为可读性的好处值得某人忘记在多个位置修复错误的风险时,我会重复自己一遍。

考虑到该建议,听起来像是您的情况

进行一些细微调整,重复几次相同的过程

我一定会努力不重复您的情况。假设最小的“调整”-可以使用影响行为的不同参数或通过注入依赖关系来执行不同的子任务来处理它们。

当看起来像快速剪切+粘贴会减少工作量时,为什么要干呢?

著名遗言。您会后悔想到,当初级工程师进行调整/修复/重构时,一个doStuff甚至根本没有意识到其他的存在。随之而来的是狂欢。随后几乎没有烧心感。每行代码都花费更多。您必须使用这么多的重复功能测试多少个代码路径?如果是一种功能,则只需通过一些行为修改就可以测试一条主要路径。如果复制粘贴,则必须分别测试每个doStuff。很可能您会错过一个机会,并且客户可能有不受欢迎的错误,并且收件箱中可能有一些不受欢迎的电子邮件。


2
嗯,只是要清楚一点,我不是建议干坏,这个问题更多是魔鬼拥护者。我真的在寻找一个逻辑上的回应,我可以链接到那些认为cut + paste + tweak代码很好的人。
隐身

2
话虽如此,我最喜欢您的答案,因为它涵盖了DRY中的两个失败:不打扰,过分沉迷以及解释影响。-关于牺牲bug可读性的观点,我认为重复代码的可读性较差,原因与您指出的相同,因为它很容易使人无法跟踪。
隐身

16
我要强调一个简单的DRY陷阱:合并了类似的代码。如果您有两个用例在功能上不相关,但是碰巧具有非常相似的代码,则由于DRY很好,因此很容易合并这两个用例。不幸的是,当需要改进时,您通常会遇到不愉快的任务,即必须再次拆分功能,然后遍历所有调用站点并仔细考虑应在此处调用的那个示例。示例:LLVM结构化类型(所有相似的类型都合并为一个)几乎不可能将IR映射回原始代码。
Matthieu M.

1
答对了。如果将更改两个或更多代码段,并且所有代码段的更改始终相同,则应将它们合并。任何需要以与其他方式不同的方式进行更改的部分都不应合并。如果代码永远不会改变,则是否合并也无关紧要。更改是应该锁定还是分离的问题比所讨论代码的大小重要得多。
超级猫2014年

1
@MatthieuM这是一个不公平的例子。LLVM正在将结构类型化作为优化 ; 也就是说,LLVM的人们决定以难以理解的IR为代价来获得性能优势。DRY通常是可维护性问题,但在这种情况下,显然是降低可维护性的故意决定。
本杰明·霍奇森

47

因为DRY以后会少一些工作。


干:(不要重复自己)

一个带有参数的函数。

def log(arg):
    print(arg)

C&P :(复制并粘贴)

26个gazillion函数执行相同的操作,但有2个字符的差异。

def logA():
    print('a')

def logB():
    print('b')

...ad infinitum...

我们如何更新打印以指定确切的打印内容呢?

干:

def log(arg):
    print(arg + "Printed from process foo")

做完了

C&P:

您必须返回并更改每个功能


您认为哪个更容易调试?


10
另外,您需要编写具有重复功能的尽可能多的相似测试套件。
9000

您已经充分说明了这个概念,但实际上,没有人会像过去那样用gazillion函数来完成您所描述的事情,无论如何也不会那样做。
罗伯特·哈维,

@罗伯特,我希望不会!我选择了一个非常简单的任务来尝试更好地说明这个概念以及为什么它可以是一件好事。
约翰

11
@Robert-您是否阅读了thedailywtf.com上的任何文章;)-那里有人可以做到这一点
HorusKol 2011年

1
@ 9000若你没有任何测试套件:P(事实上,往往可能是在某些项目的情况下...不幸的是...)
Svish

16

因为,适用于您的示例:

  • +可读性

    更少的代码通常可以减少噪音(不总是...)

  • +灵活性

    如果您不得不更改的行为,则可能doStuffX要杀死自己或写它的人,

  • +可扩展性

    如果您已经将不同的部分提取到您选择的数据结构中,然后通过调用泛型对其进行了迭代doStuff,那么您也可以在数据结构中添加一行以在其中添加新条目,或者删除一行,然后改变行为只会意味着编辑doStuff。易于维护

  • +成本效益

    更少的代码在这里意味着:

    • => 减少开发 => 降低成本
    • => 减少错误的可能性 => 减少支持时间 => 降低成本
  • +(可能)托管优化

    根据语言的不同,编译器/解释器可能有更大的机会确定泛型doStuff总是做几乎相同的事情,经常一个接一个地调用,并且可以内联它或尝试对其进行优化。可能不会针对的X个变体doStuffX

  • +测试和质量

    测试更容易:doStuff需要测试,仅此而已。好吧,不完全是,但这已经涵盖了更多。只有其IO期望值有所不同,并且需要在不同的条件下进行测试,但是与的所有变体相比,它仍然要容易得多且易于维护doStuffX

总的来说这占更易于维护的代码和提高开发效率为你的团队,这是许多好的做法一个帮助你产生更多的稳健和可靠的软件。


13

由于其他所有人在解释重复代码的可维护性问题上都做得很出色,所以我只想这样说:

许多编程要求您考虑未来,而不仅仅是眼前的现在。您是对的,现在复制和粘贴更容易了,但是声明“ 我不太可能需要在不久的将来再次进行编辑”。这表明您没有正确地思考。是的,您可能会花一点时间来购买快速而肮脏的复制/粘贴操作,但是这样做表明您无法超越当前的问题并考虑明天。您是否肯定不需要再修改此代码了?没有错误吗?您可以100%保证在需要实现下一组功能时不需要重新访问它吗?这些是明天的问题,在您今天进行设计时需要考虑。

当然,有时需要复制/粘贴。作为UI开发人员,我发现有些时候我不得不违反DRY原则。很糟糕,每次发生时我都会畏缩,而且幸运的是,这种情况很少见。但这确实发生了。

区别在于,违反DRY时,您应该有一个非常有说服力的理由,并且这样声明:“很难弄清楚如何将所有这些转变为一种直截了当的模式并不是其中之一。除非您承受着巨大的时间紧迫,并且让老板尖叫着要在接下来的几个小时内得到一些东西,否则您将失业,否则我认为这不是有效的理由。

不要以这种错误的方式来对待:我不是要对您进行责骂或责骂,而是要设法让您了解自己的心态在哪里。程序员投资于未来的懒惰;干是实现这一目标的一种方式。您今天解决难题的工作将在明天获得回报。


我不确定我是否同意老板告诉您“完成任务或被解雇”是违反DRY的重要原因。技术债务,您什么时候有时间做正确的事,真的节省时间等吗?
隐身

1
@Incognito,我试图有点讽刺意味:)
bedwyr 2011年

7

我不太可能需要在不久的将来再次进行编辑。

如果确实如此,那么您也许可以摆脱它,但是更多时候,您将要处理需要维护的代码。这意味着扩展功能,修复错误和其他改进。如果您在10个不同的地方对同一代码进行少量改动,并且有一天您需要返回该代码并需要进行更改,那么现在您就容易出错,需要在10个不同的地方进行相同的更改(很抱歉,有11个地方,您忘记了一个地方,现在却有一个bug)。

如果您可以概括要解决的问题,则可以在出现错误时使代码更易于扩展和修复。


很酷的答案,但是即使我可能会摆脱它,那么在我之后仍然需要维护的可怜的汁液又如何呢?;)。
隐身

请参阅:“您经常需要处理需要维护的代码” :)
Alex

即使如此,复制和粘贴的内容都是100%无缺陷的完美,这也是唯一的情况。事实并非如此,不要再想这可能了。
丹·雷

我会承认我过去曾经复制和粘贴过东西,但是对于我打算保留超过一天的任何事情都不会。有时,您只需要一个快速而肮脏的即弃脚本。
亚历克斯(Alex)

6

正如我在回答另一个问题时所说,我的方法如下:

  1. 第一次解决某个问题时,我就完成了。
  2. 第二次(即,当我解决类似的问题时),我想:嗯,也许我在重复自己,但现在我将进行快速复制和粘贴。
  3. 我第三次认为:嗯,我在重复自己->使它更笼统!

即直到2,另一项原则(YAGNI)胜过DRY。但是从3开始(如果我真的很懒的话,从4开始),看来我会需要它,所以我遵循DRY。

更新资料

从我最近的经验中可以得出一些进一步的想法。我必须将另一个团队开发的两个组件A和B适应/集成到我们的产品中。首先:两个组件A和B B彼此非常相似,因此,我已经为它们的体系结构有些不同而感到不安。第二:我必须适应它们,所以我很高兴使用子类并且仅覆盖我真正需要的东西。

因此,我开始重构这两个组件(每个组件都包含大约8个C ++类):我想为A和B拥有一个通用的体系结构,然后通过定义子类来添加我们需要的功能。这样,我们的两个新组件A'和B'将从现有组件中派生。

经过两周的尝试,试图从现有代码中获得一个通用且定义明确的结构,并不得不在日常会议上解释说,由于原始代码太乱,我的进步很小,然后我与老板交谈。我们观察到,除了这两个新组件A'和B'(不再需要其中的四个或六个,只有这两个)之外,我们将不需要任何其他东西。

好的,就是这样:我做了一个大规模的复制,并重命名了A和B中的类,并开始调整代码的副本。我让它在两周内可以正常工作(现在仍在进行一些错误修复)。

优点:我们的功能现在几乎已经完成,并且在修复所有错误之后,我们就完成了。我们已经保存了A和B的所有重构和测试。

缺点:两个星期前,另一个团队更改了另一个组件C,供A和B使用。他们改编了A和B,但A'和B'也坏了,我们必须自己更改它们。这引入了一个我们必须修复的新错误。如果A'和B'与A和B共享了大部分代码,那么这些额外的工作可能是不必要的。

因此:代码重复总是很危险的。我认为这总是要权衡取舍的问题,通常这并不容易。


5

只是为了澄清一下,因为我在其他任何答案中都找不到:

DRY是旨在减少各种信息重复的软件开发原理。

每条知识都必须在系统中具有单一,明确,权威的表示形式。

Andy Hunt和Dave Thomas提到的DRY原理不仅仅限于防止代码重复。它还提倡代码生成和任何自动化过程。具有讽刺意味的是,代码生成的结果甚至可能是重复的代码...

其原因已经在其他答案中得到了详尽的解释,但是Falcon的评论很好地总结了恕我直言:

单点更改更易于维护。


噢,我以为标签中有一些数据。我将在其中放置一些信息。
隐身

3

干燥太多了。发生这种情况时,两个概念在某个点上看上去非常相似,足以保证因式分解代码(1)稍后可能会变得足够不同,以至于它们值得单独实施。

换句话说,DRY和松散耦合有时会冲突。如果您希望doStuff1和朋友在该软件的每个新版本中有所不同,则可以复制他们的代码。

根据我的经验,可能很难判断您的软件将来的发展方向,因此,DRY通常是一个安全的选择。

过度“干燥”的代码通常具有复杂的控制流程和太多参数。最初是简单功能的功能后来得到扩展,以支持由额外参数控制的新功能。经过两到三遍迭代后,该函数不再可维护。修复设置中发生的错误,并在其他设置中引入新的错误。

可以理解,代码质量通常会随着代码的发展而下降,但是我看到一些案例,其中,如果体内包含if-then-else意大利面条,那么多参数函数是出于善意却执行不力的重构结果的结果。

(1)我使用的是“代码”一词,但这也适用于设计。


举一个“太干”的示例是有帮助的,因为它是频谱中不那么常见的一端。
隐身

@Incognito:我已经编辑了答案。没有具体的例子,但希望我的意思很清楚。
荷兰Joh

2

我不得不提到关系数据库世界中DRY的问题。数据库被设计为使用基于集合的逻辑并通过可查询来快速且良好地执行。DRY原理通常使开发人员编写不可保存的查询,或使用行列式行逻辑在多种情况下利用现有代码。DRY和性能优化常常是矛盾的,在数据​​库世界中,性能通常比维护能力更为重要。这并不意味着您根本不应该使用DRY原理,而应该知道它会如何影响数据库的整体可用性。应用程序开发人员首先考虑的是DRY,其次是性能,数据库开发人员首先考虑的是数据完整性,性能第二,数据的安全性(性能和安全性在某些系统中可能会互换)。

我注意到,一般来说,您在数据库查询中放入的抽象层越多,它们变得越慢。我并不是说我不希望自己设计datbase程序的人在允许开发人员使用DRY而又不影响数据库性能的情况下做得更好,但是我不设计该级别的数据库软件。 ,所以也许抽象和数据库性能之间的冲突比我想的要难解决。但是,我们必须使用当前构建的系统。我们可以要求在将来的发行版中更好地实施DRY原则,这些原则也不会损害性能(尽管多年来一直在进步,但仍然存在问题),但是与此同时,我们必须考虑DRY是否适合该数据库此时。

但是,通常要用来确保满足DRY原则的功能正是那些会给数据库造成严重问题的功能。我并不是说不要使用DRY,但不要过度使用它。

我在说什么的例子。您每月需要一次导入一百万条记录的数据。记录已经可以通过调用存储过程的用户界面手动添加。由于此过程是为单记录导入而设计的,因此一次仅添加一个记录。使用DRY避免将插入代码放在两个位置,可以编写一个游标来重复调用proc,而不是编写所需的基于集合的导入。导入时间从使用基于集合的逻辑所需的30分钟变为18小时。现在,在这种情况下坚持DRY的正确方法是修复proc以处理多种记录导入。不幸的是,将数组发送到proc常常是不可能的或非常困难的(取决于db后端),并且通过更改proc最终破坏了应用程序。

标量函数和表值函数也用于实现DRY原理,它们再次会严重影响性能,尤其是在您需要以防止索引有用的方式使用它们时。

视图也很适合实现DRY。但是,如果通过使用调用其他视图的视图的视图来实现DRY,则将很快达到查询在负载下超时的地步。实际上,当最后只需要三个记录时,您可能最终需要生成数百万条记录的数据集。因此,对于实现DRY的一组复杂的联接的单层视图非常好(我自己一个人,我们用来确保所有财务报告使用相同的基本表集和某些事物的计算),而不是两个层次您需要考虑是否造成性能混乱。


1

我没有在上面看到我的答案的要点,所以去了。不要在干看着这么多的规则做某事。可以这样说,但它确实可以达到完全不同的积极目的。这是一个停止,思考和找到更好答案的信号。寻找能够设计更好解决方案的机会给我带来了挑战。这是我代码中难闻的气味的好方面,它促使我重新思考设计,并使我的设计做得更好。DRY不仅仅只是一点点语法上的违反。模块化使我面临挑战。挑战我进行组件化。它标志着重复,提醒我要考虑使用模板和代码生成,而不是蛮力和无知。它可以帮助我弄清楚我应该花些时间来实现自动化。它导致您过节俭的生活方式!它可以帮助您将更多的时间用于制作更酷的新产品,而不是挑剔的旧乏味细节。它为您提供良好的举止,良好的呼吸和健康的生活方式!好吧,也许我有点误入歧途....


DRY对我有非常不同的影响,但是,如果这些对您有影响,我更喜欢“停止,思考和找到更好的答案的信号”以及具有挑战性的理念。
n611x007

1

我有一个旧的旧项目,其中一些以前的开发人员根本不关心DRY。因此,整个代码库中都充斥着诸如GetSystemTimeAsString(),LogToFile()之类的辅助方法以及许多其他内容。有些方法是为满足特殊需要而略微定制的,但是大多数只是复制和粘贴。

不幸的是,某些方法在某些情况下使用了诸如strcpy()之类的不安全的东西,有一些像char数组这样的微不足道的错误,在某些情况下还不够长。

因此,找到所有代码片段,协调它们并修复错误是真正的PITA。而且我们仍在协调和修复问题。

您永远不会知道,如果您在第一种方法中犯了一个错误,然后不得不多次修复,因为您只是复制了它。而且,如果您以后想使用某些方法,您怎么知道,现在代码库中的5种方法中哪一种适合您的情况?因此,您只需复制一个,对其进行自定义,然后就可以再次开始...


1

是的,如果您正在编写Throwaway Code,请不要担心DRY 。

但是,如果您打算保留代码,那么DRY当然很重要。


1

措辞“不要重复自己”有点过于简单化。重要的是“避免将一个可能更改的信息封装在两个独立的位置”。

如果程序应该处理小部件,则每个小部件具有三个woozle,并且具有许多形式的循环

for (i=0; i<3; i++)
  thisWidget.processWoozle(i);

那么期望小部件将包含三个woozles的期望将封装在这些循环的每个循环中,并且更新代码以容纳每个小部件的任何其他数量的wizzles可能会很困难。相比之下,如果有人要说

#define WOOZLES_PER_WIDGET 3

每个循环都被重写

for (i=0; i<WOOZLES_PER_WIDGET; i++) ...

这样的设计可以很容易地更改每个小部件的尾声数量。

但是,需要注意的重要一点是,虽然希望将每个小部件的小节的数量等信息整合到一个点,但这并不总是可行的。有时可能需要对逻辑进行硬编码,这仅在事物具有特定大小时才有效。例如,如果每个woozle都有一个值,并且想要找到与特定小部件关联的中位数,则可以对这些值进行排序并取中间值,这样的方法将适用于任意数量的woozles,但是逻辑上专门用于查找三个项目的中位数的手写方法可能会明显更快。

尽管具有WOOZLES_PER_WIDGET常量可以使代码更具可读性,但应注释一下以明确其值不能更改,除非对程序逻辑进行其他调整。在那种情况下,对三个项目进行硬编码的逻辑和常量WOOZLES_PER_WIDGET都将复制信息“每个小部件具有三个魔鬼”,但是这种复制的好处(更大的执行速度)可能会超过成本。


0

虽然我实际上同意其他张贴者关于可维护性等的评论,但所有这些都是有效的。

我想在辩论中发表一点反对意见。

  • 这对程序员而言仅重要。只要软件通过UAT,支付工资的人就不会在乎。
  • 在重要性方面,它排在以下各项以下,例如获得正确的要求,听取项目发起人的意见并按时交付。

因为该站点是针对“程序员”的,所以我可以肯定地说这个问题是针对“程序员的观点”的。您关于工资支付者,UAT和重要级别的陈述当然是有效的,但与该特定问题无关。
ozz 2012年

1
我完全不同意。如果对其进行了详细说明,则好的管理人员将理解其原理以及为什么要执行这些原理。这应该是认真的深入对话,而不是一分钟五分钟的时间。
Michael Durrant 2012年

2
您的第二个要点是完全正确的。
Jim G. 2012年

1
@Ozz,对一个优秀的程序员来说,以您的手艺为傲甚至很重要,但是,也许“程序员的观点”应该包括对“客户满意度”的一点关注。
詹姆斯·安德森

0

<tl;dr>

我无法阅读所有重复的答案,因此我可能错过了一些内容(我自己会重做<=看看我在这里做了什么?)。

这是关于防止代码重复的一些很棒的事情!

  1. 易于测试:您只需测试代码的一个“副本”。
  2. 易于修复:您只需在代码的一个“副本”中找到该错误,并对其进行一次修复。
  3. 更新更容易(与上面相同):所需的更改通常可以在很少的地方通过修改代码来处理,因为您花了一些时间正确地重用代码,并且没有将相同的行复制到源代码中成百上千的不同位置。
  4. 易于重用:当(在某些地方没有重复)并保存在通用的,恰当命名的方法中时,很容易找到它们并使用它们,而不必编写自己的方法。
  5. 易于阅读:重复的代码由于不必要的冗长而难以阅读。它包含很多行,这些行不是逻辑和特定的预期功能的一部分(例如,用于设置要执行操作的阶段的通用命令,或者许多地方需要的通用简单重复任务)。干净的代码会弹出逻辑和功能,因为没有重复会浪费代码空间。
  6. 由于(1)和(5),调试起来更容易。
  7. 节省您的时间和金钱,并在将来做更多有趣的事情;专门创建更好,更健壮的代码。这是底线,几乎是所有上述内容的总和。如果很多人使用相同的功能doFoo1(a, b),则很有可能会发现并解决许多烦人的错误和边缘情况。如果每个人都复制代码并创建doFoo2(specialA)...,doFuu2^n(a, b, c)那么他们会重复这些问题doFoo1并具体创建更多的工作。

</tl;dr>

长版:

代码重复的问题在于,它“呈指数增长”(换句话说,它迅速扩展),原因是当您重复代码时,您在不知不觉中授予他人许可(对于一个人,您不再有能力对其进行判断)并且您鼓励他们也这样做。您也很难避免,因为当源中有很多令人困惑的冗余重复时,很难发现和重用有用的代码。特别是如果代码尚未提取到适当命名的函数中。因此,如果您遇到一个常见的易于解决的问题,则可能会自己编写一段代码来解决该问题……并且您可能无法检查一些边缘情况,从而添加了更多有问题的未经测试的代码。

另一件事是,对于一个新手来说,这听起来像是一个只会影响大公司的问题,但我发现它对小型初创公司的影响非常严重(如10,000行重复的服务器端代码)。这是一种心境。您不仅应该掌握DRY,还应努力鼓励其他人也这样做。因为否则,您将注定要重复大部分代码。当DRY手段可以执行时,使用它们就容易得多。当有很多重复的代码时,应用复制粘贴解决方案要容易得多。

我发现代码重复有害:

  1. 这个功能可以使用吗?比方说,您找到了一个可以执行(或看起来执行了您需要的操作)的函数,如何知道它是否应该正常工作,或者仅仅是被复制和放弃的代码。
  2. 冗余代码。有时人们会重复使用,忘记代码(以后总是可以再次重复代码)。有时,有人会在某些地方删除对重复函数的调用,以进行重构,但是即使未在积极使用它,未使用的函数也会保留下来。
  3. 很难找到您想要的东西。重复的代码会占用空间,并且使找到有用和需要的东西(使用grep之类的工具)比完成一项艰巨的任务更为困难,因为要获得成千上万的结果,而本来应该只有很少的结果。
  4. (之前已经提到过):难以维护,但也难以用于维护和回归目的。如果测试代码重复并且没有正确提取到函数中,则其他人将重复它。有人会费心编写易于使用,易于阅读的API来使QoL更好吗?根据我的经验,没有,人们常常认为某些事情更紧迫,直到事情失控。
  5. 代码重复更难阅读,因为它会使代码变得不必要的冗长,在冗长的代码不会添加有关预期功能的信息的地方:例如,[一遍又一遍地]为多种预期功能奠定基础,使这种实际功能更难以弹出。
  6. 这已经被提及很多了。如果代码错误,则一些可怜的女孩或家伙将需要搜索和更改该代码的每次使用。例如,如果有人在有需要的有组织的类中的极少数地方使用了对mysql_query的SQL注入不安全调用,则很容易修复它并改用PHP PDO,但是如果他们在上千个地方使用了它,再者,修复它实际上将需要外包,有时甚至更危险,因此将需要从头开始重写代码。
  7. 复制代码是一个坏习惯。如果您练习某事,它会慢慢成为第二天性,它会影响您周围的人。初级开发人员会看到您做到了,并且也做到了。您应该练习讲道,养成做正确事的习惯。您了解更多。编写非重复的代码更加困难,也更具挑战性。这是一个有益的习惯。

关于防止过度代码重复和总结的最后说明:

之前也曾说过这一点,但有时避免重复会导致您“向后弯腰”并且做的事情太复杂(或不重要),以至于其他人无法理解。即使不涉及防止代码重复,编写不可读的代码(或我们戏称它为“保留工作”的代码)本身也是一个问题。但是,我发现,如果从一开始就灌输了正确的基础架构和最佳实践,那么防止代码重复就容易得多,人们通常可以避免做不直观的事情,因此可以防止将来为防止代码重复而进行不必要的,不可读的工作您从那开始就正确地做事。

正确的做法是什么?嗯,这是一个很难回答的问题,但一件事是定义项目需要哪些方法,并查看公司内(外部和内部)其他人已经实现了什么,并在可能的情况下重复使用;记录您添加到代码库中的所有内容,并尝试使其比必须的通用性高一个档次,仅此而已。不要过度设计模式只是为了使代码在不需要的地方变得灵活。

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.