什么时候停止干掉代码?

时间:2009-10-07 06:16:12

标签: ruby-on-rails ruby dry design-principles

所以干掉代码应该是好事吗?我正在研究的一个项目中存在某种情况,其中某些模型/实体除了使用它们的上下文之外或多或少相同。也就是说,每个这样的实体都有标题,描述,标签,user_id等以及一些其他属性。因此,他们在各自控制器中的CRUD操作看起来非常相似。

我的经理认为重复代码并需要进行干预。因此,他提出了CRUD ruby​​模块,当include d处理所有这些实体的控制器的CRUD操作时。但最终,Simplicity受到了损害。代码失去了可读性,因为每个“东西”都被命名为“对象”。调试变得困难,干掉代码的重点就丢失了。

这只是一个案例。其中有几个是DRYing up导致复杂,难以调试的代码。所以问题是,我们什么时候停止干扰代码?因为并非每次你都意识到代码已经失去了简单性(而且代码作者通常从未意识到代码的简单性会丢失)。另外,如果我们必须在简单和DRYed代码之间做出选择,那么应该选择什么,如果有的话,你可以只获得其中任何一个。

8 个答案:

答案 0 :(得分:4)

据我了解,如果干扰代码导致简单性丢失,我们正在做一些非常错误的事情。我认为,我们应该重新编写重复的代码并承担单一责任。如果代码职责不同和/或实体的抽象无法命名,我们就不会重复代码。代码模式可能会重复,但它的代码完全不同,并且具有自己的责任。如果DRYing导致代码模糊,那么您可能正在尝试使用具有类似模式的不同职责来干掉代码,这实际上并不是一个好习惯。干燥应该增强简洁性,而不是抑制它。

答案 1 :(得分:2)

如果您正在关注REST,那么是的,控制器将非常相似,并且主要是样板。我同意你的经理这是一个问题。

听起来好像他想出了一个次优的解决方案。如果想要更好的,请查看正在inherited_resources plugin的Jose Valim的incorporated into Rails 3

答案 2 :(得分:0)

可读性和可维护性是良好代码的两个最重要的特性。不幸的是,有时必须妥协。这是一个平衡问题,并不是每个人都会同意。

我自己,我也倾向于你的观点。如果这意味着代码更容易理解,我宁愿有一些明显的重复。

答案 3 :(得分:0)

至于“调试”问题,当我创建这样的“基类”以包含补充字段时,我就习惯了。该字段是一个简单的字符串,用于标识派生类最多的类(因此从Constructor传递给Constructor)。然后每条消息都打印这个字段+对象id“realtype [id]”,一切都突然变得容易调试。

现在开始干。

DRY有两件事:

  • 构建层次结构
  • 使用通用代码

现在应该很好地理解第一点。类的层次结构意味着IS-A关系。如果两个类具有相似的行为但在功能上不相关,那么它们不应该是同一层次结构的一部分。它只会让可怜的维护者感到困惑,并且会伤害可读性。

第二点可以更频繁地使用,尤其是脚本语言。对于先前的例子,我认为不是拥有类的层次结构,而是简单地定义通用方法,这些方法将采用不同的类(建模不同的业务)并统一处理它们。这样你就可以避免重复(干)但你不会牺牲可读性(imho)。

My 2 cts。

答案 4 :(得分:0)

如果每个人都直言不讳地告诉我 - 我的代码需要DRYing,我可能会认为这是他们要做的其他任何事情都会变得非常牵强的标志。 -sake-的-它。

话说回来,编写代码(懒惰)的简单性和代码本身的简洁性(优雅)之间也存在差异。不过,我同意这是平衡的。我曾经在某个特定时间遇到这种情况(在PHP中,但是它如何让我想起你的困境):

$checked = ($somevariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $disabled_checked />";
$checked = ($someothervariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $checked />";

这甚至不是我正在处理的一个很好的例子。从本质上讲,因为它是一个无线电输入,两个输入都需要一定程度的知道哪个被鼓泡。我知道它有你的老板可能称之为“潮湿”的问题,所以我绞尽脑汁试图想出一些解决方案,会很优雅而且非常重要。最后,我向一位高级开发人员展示了它,他说:“不,这一切都井井有条,它做了它所需要的。它只是一条额外的线条。”

我感到很欣慰的是,我被提醒说我正在伤害我的项目,然后担心这一点,但与此同时,我仍然感到失望的是他对一个基本原则如此随意(好像它不是'他的一个,虽然我确定是。)

所以,虽然我同意,你的经理可能只是为了做到这一点,但只有当我们努力想出更好的方法和方法时,我们才能获得更好的语言,如Ruby和Python以及更酷的库,如Jquery的。

基本上,如果下周你突然有70 things而不是2?如果你的老板的对象突然变得那么快,他就是对的。如果它是相同数量的麻烦(在代码或执行中),他错了。但这并不意味着没有更好的答案,而是保持简单,因为它只是一些事情。

答案 5 :(得分:0)

DRY原则的目的是帮助提高代码的“质量”。

如果更改未提高代码质量,则需要停止。 判断这一点的能力来自于经验。随着需求的变化,重构代码的最合适的方式也会发生变化,所以不可能让一切都理想 - 至少你需要先冻结需求。

最小化代码的大小通常不应该考虑质量,除非你是代码转换,所以当唯一的目的是减少代码的大小时,不要干。

复杂的技巧可能弊大于利。

答案 6 :(得分:0)

应用DRY提高可维护性的一个关键原因是确保在需要更改代码时,只需在一个地方进行更改,从而避免的风险在需要它的任何地方变得更新。

但我不是在讲述整个故事:

This interview with Dave Thomas有DT说:

  

DRY说每一个系统   知识应该有一个   权威,毫不含糊   表示。

我第一次看到“干”出现在The Pragmatic Programmer,所以我倾向于和Dave一起去。

另一篇值得一读的文章here

但是DRY是一个原则,而不是一个规则:我们越了解原则,就越能够识别应该应用的情况。

(最后,在我开始“干掉”代码之前,我想我还想要“或多或少相同”:如果我能看到两种情况可能分歧的清晰方式在未来,我会倾向于让他们独自一人。)

答案 7 :(得分:0)

对我来说,重复的代码是一种可以有多种来源的气味:

  • 缺少变量(引入变量)。
  • 缺少方法(将表达式推送到方法中)。
  • 功能羡慕(将行为推向羡慕的类)。
  • 过度泛化(将泛型类分解为特定的具体类)。
  • 抽象不足(将属性和行为推送到新类中)。

此列表可能不完整。把它视为一个起点。

当您发现重复时,请考虑它的症状是什么问题。然后尝试解决这个问题。完成后,请考虑新代码的可读性。如果它已经恶化,你可能处于以下其中一个位置:

  • 你在复制的根源错误地识别了问题(还原,重新考虑,再试一次)。
  • 复制是必要的权衡(恢复您的更改并与之共存)。
  • 您的软件必然很复杂(提交您的更改并使用它)。

如果可能的话,考虑发布示例代码以及类似的问题。它们提供了一些具体的解决方法。请记住,很多这些东西都是非常主观的。