是否具有相同方法的两个版本,它们的签名(方法名和“ throws”属性)仅不同(设计名称不同)?

时间:2019-05-25 06:07:29

标签: java exception indexoutofboundsexception api-design

我想设计一个API,其中我有两个版本的同一方法extractLastElement()

  1. 第一个版本将没有throws属性:Object extractLastElementSafe();将在客户端“肯定知道” 包含集合中的元素(例如,他已经刚刚添加了一些元素,因此不需要try-catch样板代码。

  2. 第二个版本将引发Checked Exception:Object extractLastElement() throws NoMoreElementsException;如果客户端不确定集合中是否还有剩余元素(例如在循环内),将由客户端使用。

这被认为是不好的设计吗?有没有其他替代方法可以模仿这种行为?

public class SomeCollection {

  private List<String> arr;

  public SomeCollection(List<String> arr) {
      this.arr = arr;
  }

  public String extractLastElementSafe() {
      return arr.remove(arr.size() - 1);
  }

  public String extractLastElement() throws NoElementsLeftException {
      try {
          return arr.remove(arr.size() - 1);
      } catch (IndexOutOfBoundsException e) {
          throw new NoElementsLeftException(e); // throwing a checked exception
      }
  }
}

class NoElementsLeftException extends Exception {
  public NoElementsLeftException(Throwable cause) {
      super(cause);
  }
}

2 个答案:

答案 0 :(得分:4)

赋予用户以不同方式做相同事情的能力总是有问题的。强迫客户担心最后一个元素是否存在也不太好。

但是最后,这更多是一种风格,您的方法可以认为还可以。尽管如此,您仍然向客户端公开了调用“安全”方法的方法,并最终导致运行时异常。因此,实际上实际上有两种不同的错误情况。

必须改变的一件事:避免代码重复!执行try / catch引发该异常的方法应该只调用“安全”方法!

说了这么多:我个人只提供一种抛出某些运行时异常的方法。标准Java集合使用未经检查的异常,您也应该这样做。

引用罗伯特·马丁的话:“已检查和未检查的异常之间的战争已经结束,未检查的异常赢得了胜利”。他在十多年前写了这封信。

答案 1 :(得分:1)

如果每种方法的版本都有明确定义的使用方案,则应同时使用这两种方法。此类设计决策的示例可以在类Queue中找到,该类在两种模式下工作,例如,尝试从空队列中删除元素时:一种方法(poll)返回null,而另一种方法返回null。 (remove)引发异常。