3

我正在开发一个名为 的简单类,Simulator它将 s 列表应用于Simulation某个输入。对于每个输入,模拟可以产生或不产生输出,这取决于输入对于每个模拟必须满足的某些条件。产生的结果Simulator是一个输出列表。

这是代码。

class Simulator {
    final List<Simulation> simulations;

    // Some initialization code...

    List<Ouput> execute(Input input) {
        return simulations
            .stream()
            .filter(s -> s.processable(input))
            .map(s -> s.prepareOutput(input))
            .collect(Collectors.toList());
    }
}

如您所见,首先我验证输入是否可由 a 处理Simulation,过滤不能处理的模拟,然后将这些模拟应用于输入。

从面向对象的角度来看,我暴露了Simulation类的内部结构。方法所做的检查操作processable应该隐藏在prepareOutput方法内部。

但是,由于对processable可见Simulator,我可以应用更实用的方法,这非常方便。

哪种方法更好?我还缺少其他解决方案吗?

4

2 回答 2

4

由于您的课程Simulation已经公开了可能失败的操作,因此当您提供提前检测操作是否失败prepareOutput的方法时,没有额外的公开。实际上,提供这样的检查是一个很好的 API 设计,只要预先计算的成本不会太高。processableprepareOutput

您仍然可以考虑Simulation课堂上提供批量处理操作。

public class Simulation {
    public Output prepareOutput(Input input) {
        …
    }
    public static List<Output> prepareWhenPossible(List<Simulation> list, Input input) {
        return simulations.stream()
            .filter(s -> s.processable(input))
            .map(s -> s.prepareOutput(input))
            .collect(Collectors.toList());
    }
}

重要的是要让调用者清楚,它将跳过无法操作的元素,而不是实现“全有或全无”行为。

processable如果实施起来很便宜,这仍然不排除公开。这并不是一个不可能的操作,因为总是可以调用prepareOutput并删除结果来确定该操作是否可行。有一个processable为此目的的方法要干净得多。

于 2017-03-27T11:45:57.570 回答
1

如果你需要隐藏processable,为什么不做一些不同的事情:

 Optional<Output> prepareOutput(Input input) {

      boolean isProcessable = processable(input); // processable is private

      if(isProcessable){
            // prepare Output
            return Optional.of(Output);   
      }
      return Optional.empty();

 }

然后是这样的:

  List<Ouput> execute(Input input) {
    return simulations
        .stream()
        .map(s -> s.prepareOutput(input))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());
 }
于 2017-03-27T11:05:46.393 回答