【问题标题】:Delegate objects produce duplicate code: (inheritance vs delegates)委托对象产生重复代码:(继承与委托)
【发布时间】:2017-04-06 16:05:43
【问题描述】:

我在 OOP Java 世界中遇到了一种情况,这让我在寻找构建“可测试性”代码的理想方法时遇到了困难。我所做的研究主要针对代表,这是一个很酷、很直接的pattern,但是,我相信它会导致大量重复代码。

总之,我有一个包含一些冗长方法的类。我有第二个类,它“扩展”了上述冗长的类并覆盖了一些上述方法。第二个类调用 super 方法同时覆盖原来的方法(因此第一个类对于减少代码是完全必要的)。

示例: 被剥离的父母:

public class ParentClass {

  public void methodX(final int source, final int target) {
   ++++
   ++++
   ++++
  }
}

脱衣舞的孩子:

public class ChildClass extends ParentClass {

  @Override
  public void methodX(final int source, final int target) {
    super.methodX(source, target)
    ****
    ****
    **** // extra logic
  }
}

我的想法和问题:

为 ChildClass(扩展和覆盖其父方法的类)编写测试类非常困难,因为我们称之为超级方法! super 方法对于避免重复测试代码非常关键,即测试 ParentClass 的代码必须在 ChildClass 中使用。我可以使用 Mockito 手动模拟很多这些内部方法,但这绝对是一种糟糕的做法。

我的问题:

这是使用超级方法或扩展这样的类的公平方式吗(应该避免子类——组合>继承)? 每当我们测试子类时,是否需要测试 ParentClass? 将使用哪些设计模式来适当地重构代码以避免这种情况?

【问题讨论】:

  • 尽管组合比继承更受青睐,但不幸的是,在 Java 中设置委派给组合的样板代码是必需的——这太糟糕了。有一些语言可以自动为你做这个委托——例如,有 JVM 语言 Kotlin,我相信 golang 做同样的事情。专注于减少 Java 样板代码的 Lombok 项目有一个“实验性”委托功能,您可能想看看:projectlombok.org/features/Delegate.html

标签: java oop design-patterns delegates


【解决方案1】:

我认为您的输入中有各种“气味”:

  • 您从违反 Java 编码约定开始。类名以大写开头;但这只是一个旁注。
  • 我看到的第一个真正的问题:methodX() 的多个实现;并将对 super 实现的调用作为子类覆盖中的 essential 部分。这会在您的类之间引入非常紧密的耦合。

我会从这一点开始 - 并考虑摆脱它;但如果您不能或不想这样做;那么绝对有必要不要“嘲笑”那个超级电话。您想确保您的子类测试确实运行它们所依赖的代码。

相反:如果您发现如果没有那种嘲笑技巧就无法合理地测试您的子类;那么这是另一个表明你的代码库中有问题的迹象。

【讨论】:

  • 原谅样式错误(这是在没有 IDE 的情况下即时完成的)。联轴器的优点。我们假设 super 调用是扩展类的本地部分,因此对测试同样重要。你会如何推荐我们“解耦”这些类?我知道我们可以创建一个辅助类。我们是否可以进行其他设计更改以遵循某种模式?
  • 今天我快结束了。我发现你的例子有点不具体,让我想出好主意。但如果你愿意添加“更多代码”;给我留个便条,我可能明天看看。
  • 如果您愿意,请随时添加其他评论(您的回复已经足够且感谢)。我将添加一些示例代码,但考虑到我的情况,所述代码的内容并不重要......实际上,所有代码都可以是打印语句,它不会产生任何影响。
【解决方案2】:

是的,这是一种公平的方式。

扩展意味着定义一个“是”的关系。

马自达就是汽车。

因此,测试马自达实际上可以做 Car 所做的一切是公平的(也是必要的),而且马自达可以重复使用 Car 的所有功能是非常好的。

为避免(或尽量减少)CarTestMazdaTest 之间的代码重复,您可以使用 CarTestHelper,并将您想要重用的所有测试代码放在静态帮助方法中。

【讨论】:

  • 我同意你的观点。我认为你最好的补充是帮助类。
猜你喜欢
  • 2017-11-07
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2011-06-16
  • 2013-06-10
  • 1970-01-01
  • 2011-01-12
相关资源
最近更新 更多