DRY不相关但几乎相同的代码


34

我有一些几乎相同的代码,但是在主变量上使用绝对不同的类型,它们之间没有继承。具体来说,我正在用Roslyn针对C#和VB.NET编写具有以下类型的分析器:

Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax Microsoft.CodeAnalysis.VisualBasic.Syntax.AttributeSyntax

我想知道是否因为代码在做相同的事情,我应该将其保持为DRY,将其尽可能少地拆分为单独的(但类型除外),还是将它们完全分开,因为这两种方法是不相关,将来的更改可能会迫使一个版本更改,而另一个版本则不能更改(尽管这不太可能)?

编辑:大约一年后,我遇到了同样的问题,罗斯林(Roslyn)团队帮助我解决了这个问题:编写一个采用泛型并具有TAttributeSyntax完成大部分工作的参数的基类。然后,使用最少的需要特定类型的数据编写派生类。


创建自己的AttributeSyntax接口是否可以工作,该接口可以包装现有的类,但可以为您提供概念上应该存在的继承?
Winston Ewert 2015年

7
抱歉,如果这很明显,但是存在泛型,因此您不必为相同的代码(对于类型)重复自己。如果这不是您的意思,请忽略。
戴维斯洛

@Lorhead通常,我会这样做,但这是传递给单个方法的类型,该方法包含一个节点,该节点是我无法控制的内部方法的有效载荷。
Hosch250

@WinstonEwert我将对此进行调查。我不确定我是否想对所有C#/ VB.NET类型都执行此操作。
Hosch250 2015年

1
重构会带来很多折衷,有时甚至会带来悖论。例如,松耦合与DRY或短功能相对,但其中许多与较长的功能相对,而其中很少。最后,这是一个困难的野兽:您的目标是可读性和可维护性。您需要将其看作是第一次看到您的代码的化身。有时您只是尝试看看有什么更好的方法。不幸的是,不可能进行完美的重构。
phresnel

Answers:


111

您不进行DRY操作是因为有人将它写在一本很好的书中,而您进行DRY操作则是因为它实际上具有明显的好处。

特别是从这个问题:

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

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

因此,基本上,不要以为“哦,伙计,这段代码非常相似,也许我应该重构以免重复我自己”。认为“不重构重用共同元素使代码,使这个代码库更易于维护更少的维护?” 然后,选择使其更易于维护的一个。


话虽这么说,给定SRP并只是尝试一般地使用小型,灵活的类,出于这个原因分析代码可能是有意义的,将使用泛型类型(您说它们与类型相同)的行为分解为几部分小班。然后,您会发现其中的某些类实际上完全相同(而不仅仅是大部分相同),然后可以构建一个工具箱以防万一要添加Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax


32
TL; DR-DRY是达到目的的一种手段。专注于最终目的,而不是手段。如果我能两次投票赞成乐高积木,那我会。

一个重要的提示:如果你重复自己,总是在评论提及的所有其他地方有要访问的重复的代码更改时。它不仅减少了不同步的可能性,而且还可以指示重复造成的维护负担。
Xion
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.