【问题标题】:Functional style recursion with Guava?使用 Guava 进行函数式递归?
【发布时间】:2012-09-07 17:04:47
【问题描述】:

我有一个MyService 接口和MyServiceImpl 基本实现。 我将MyServiceImpl 包装成MyService 装饰器链。

为此,我创建了一个MyServiceDelegate,它是一个抽象类,采用MyService 实例并将所有服务调用委托给提供的MyService 实例。

但在我的单元测试中,出于特定需求,我需要找回MyService 的第一个真正实现,即MyServiceImpl,而我只有一个MyService,它指的是一个装饰器。

我只是想知道是否有可能使用 Guava,以一种功能性的方式进行递归,这将返回给我已装饰有很多层且不是委托服务的“原始服务”。 我想使用像 Function 这样的函数来返回委托服务,如果是原始服务,则返回 null,但不知道要使用它。

我知道我可以通过 while 循环轻松做到这一点,而且我不是在寻找替代解决方案。就是想知道Guava能不能解决这类问题。

【问题讨论】:

  • 为什么?解决这个问题的正常方法是测试可能的最小元素。换句话说,每个装饰器都是独立测试的,最终实现也是如此。功能测试可以测试整个堆栈,但功能测试真的应该关心哪个类在做什么工作,只是工作发生......
  • 我知道,我的装饰器已经过测试。这是一个集成测试,作为类集成的一部分,我需要我的装饰器进行测试。
  • 那么为什么您的集成测试关心您正在使用的实现。这种方式会导致脆弱的测试。您的集成测试应该只关心整个结构是否按照您的要求...
  • 因为我的测试 MyService 实现是一个记录服务调用的模拟,我需要检索结果。由于我无法通过接口检索调用,也无法将装饰器转换为 RecorderService,因此我需要让最终委托能够将其转换为 RecorderService,然后在我的单元测试中检索 MyService 调用。我不能轻易改变这一点。

标签: java recursion functional-programming guava


【解决方案1】:

您甚至不需要 while 循环或 Guava。只需在您的界面中添加以下方法:

public MyService undecorate();

然后是委托中的以下实现:

return decoratedService.undecorate();

以及“真实”实现中的以下实现:

return this;

如果接口无法修改,请在外部进行:

public MyService undecorate(MyService service) {
    if (service instanceof MyServiceDelegate) {
        return undecorate(((MyServiceDelegate) service).getDecoratedService());
    }
    else {
        return service;
    }
}

【讨论】:

  • 是的,它仍然相当于“替代解决方案”。可以有很多奇特的方法来做到这一点,以访问者为例 :D 但这不是我想要的
  • 实际上,我不明白你在问什么。 Guava 无法为您神奇地实现这一点,而且由于解决方案长达 3 行,我真的不知道它会带来什么。所以我想答案很简单:没有:番石榴无法解决这类问题。
  • 好的,这就是我要找的:有没有更简单的方法来使用 Guava。
  • @SebastienLorber 澄清 - 不。这不是很简单吗?为什么要只使用番石榴?
猜你喜欢
  • 2020-09-09
  • 2013-03-16
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2010-09-20
相关资源
最近更新 更多