Java API 中断

发布于 2024-07-25 13:11:21 字数 856 浏览 2 评论 0原文

我有以下 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 是由“新”条件引发的。

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

您对此有何看法?

I have the following API:

public interface MyApi {

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

I am now performing the following modification in my API implementation

public class MyApiImpl {

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

is replaced by :

public class MyApiImpl {

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

Do you consider this as an API breakage ?

Client's code will still compile but method contract defined by the API javadoc is no more respected since MyExcepiton is thrown by a "new" condition.

If only my API jar file is updated, clients application will still work but depending on the way clients catch the exception the application behavior can change a lot.

What's your point of view on that ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

最终幸福 2024-08-01 13:11:21

是的,当 C1 不发生时,您通过抛出异常来破坏接口的契约。

根据经验,接口契约越模糊,就越容易不被破坏:) 如果接口不是根据显式 C1 定义的,但在更一般的术语中,这会提供更多的灵活性。

Yes, you're breaking the contract of the interface by throwing an exception when C1 doesn't occur.

As a rule of thumb, the vaguer the interface contract, the easier it is not to break :) If the interface isn't defined in terms of an explicit C1, but in more general terms, that gives a lot more flexibility.

狼亦尘 2024-08-01 13:11:21

我的观点是,您不应该更改文档中 API 定义的契约。 如果您需要新行为,您应该 a.) 创建一个可由客户端调用的反映此新行为的新方法,或者 b.) 与客户端讨论更改的必要性并让他们意识到这一点。

这确实可以是双向的,具体采用什么方法取决于您和您的客户。

My point of view is that you should not change the contract defined by the API in the documentation. If you need new behavior you should either a.) create a new method that can be called by the client reflecting this new behavior or b.) discuss with the client the need for the change and make them aware of it.

This really can go both ways, it is between you and your clients as to what your approach will be.

水染的天色ゝ 2024-08-01 13:11:21

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

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

It largely depends on what c2 is. Is it within the logical bounds on the pre-existing contract? If so, you're satisfying the contract by throwing a MyException. If not then perhaps you need to throw a new type of exception.

I should point out that I'm not a huge fan of checked exceptions. Ultimately, forcing someone to deal with an exception doesn't necessarily make their code any better or safer (in fact it can have the opposite effect as they can sloppily swallow spurious exceptions).

我只土不豪 2024-08-01 13:11:21

我会说“不”,不会破坏 API,除非 MyException 是 RuntimeException。 那么就是了。

无论如何,我会为条件 C2 子类化 MyException

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

I'd say "no", no API breakage, unless MyException is a RuntimeException. Then it is.

Anyway, I'd subclass MyException for condition C2

And both conditions C1 and C2 should be "exceptional" IMHO, I would not make an habit of throwing exceptions

秋风の叶未落 2024-08-01 13:11:21

这是一个破损。 API 是由语言构造强制执行还是只是记录下来都无关紧要。

这种破坏是否会导致客户端代码出现问题是另一个问题。 可能您正在修复一个缺陷,需要用这种方式覆盖案例 C2 来修复它。 从这方面来看,客户端代码开发人员可能会很高兴您做出了此更改(假设他们当前没有以在面对更改时会崩溃的方式解决缺陷!)

It's a breakage. Whether the API is enforced by language constructs or simply documented is irrelevant.

Whether this breakage causes a problem for client code is a different question. It may be that you are fixing a defect and need to cover case C2 in this way to fix it. From that respect client code developers may be happy that you've made this change (assuming they are not currently working around the defect in such a way which would break in the face of the change!)

风铃鹿 2024-08-01 13:11:21

我认为这里的问题是你制定了接口的一部分,实现了特定的条件。 如果“C1”条件只是实现的一部分,那么您可以简单地创建一个新的实现,在“C1”或“C2”上引发异常,而不会破坏接口。

I think the problem here is that you made part of your interface, implementation specific conditions. If the "C1" condition were only part of your implementation, then you could have simply created a new implementation that throws an exception on "C1" or "C2" without breaking the interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文