我有以下API:

public interface MyApi {

   /**
    * Performs some stuff.
    * @throws MyException if condition C1
    */
   public void method() throws MyException;
}

我现在正在API实现中执行以下修改

public class MyApiImpl {

   public void method() throws MyException {
     if (C1) {
       throw new MyException("c1 message");
     }
     ...
   }
}

替换为:

public class MyApiImpl {

   public void method() throws MyException {
     if (C1) {
        throw new MyException("c1 message");
     } else if (c2) {
        throw new MyException("c2 message");
     }
     ...
   }
}

您认为这是API破损吗?

客户端的代码仍然会编译,但API javadoc定义的方法契约不再受到尊重,因为MyExcepiton被<!> quot; new <!>引发;条件。

如果只更新了我的API jar文件,客户端应用程序仍然可以工作,但根据客户端捕获异常的方式,应用程序行为可能会发生很大变化。

你对此持何看法?

有帮助吗?

解决方案

是的,当C1没有发生时,你通过抛出异常来破坏接口的合同。

根据经验,界面合约更加模糊,更容易破坏:)如果界面没有用明确的C1定义,但更一般地说,这提供了更多的灵活性

其他提示

我的观点是,您不应该更改文档中API定义的合同。如果你需要新的行为,你应该a。)创建一个可以由客户调用反映这种新行为的新方法或b。)与客户讨论变更的需要并让他们意识到它。

这真的可以两种方式,在你和你的客户之间,你的方法将是什么。

这在很大程度上取决于c2是什么。它是否在预先存在的合同的逻辑范围内?如果是这样,你通过抛出MyException来满足合同。如果没有,那么也许你需要抛出一种新的异常。

我应该指出,我不是检查异常的忠实粉丝。最终,强迫某人处理异常并不一定会使他们的代码变得更好或更安全(事实上它可能产生相反的效果,因为他们可以轻易地吞下虚假异常)。

我会说<!>“;没有<!>”,没有API破坏,除非MyException是RuntimeException。然后是。

无论如何,我为条件C2

创建了MyException子类

条件C1和C2都应该是<!>“例外<!>”;恕我直言,我不会养成抛出异常的习惯

这是破产。 API是由语言结构强制执行还是简单记录是无关紧要的。

这种破坏是否会导致客户端代码出现问题是一个不同的问题。可能是您正在修复缺陷并需要以这种方式覆盖案例C2来修复它。从这个方面来说,客户代码开发人员可能会对您做出这样的改变感到高兴(假设他们目前没有以这种方式解决缺陷,这种方式会在变化面前崩溃!)

我认为这里的问题是你已经成为界面的一部分,具体实现了具体条件。如果<!>“C1 <!>”;条件只是你实现的一部分,那么你可以简单地创建一个新的实现,在<!>引发异常; C1 <!>;或<!>“; C2 <!>”;没有破坏界面。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top