Вопрос

У меня есть следующий 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 выбрасывается " новым " состояние.

Если обновляется только мой jar-файл API, клиентское приложение все равно будет работать, но в зависимости от того, как клиенты перехватят исключение, поведение приложения может сильно измениться.

Какова твоя точка зрения на это?

Это было полезно?

Решение

Да, вы нарушаете контракт интерфейса, создавая исключение, когда C1 не происходит.

Как правило, чем сложнее контракт интерфейса, тем проще его не нарушать :) Если интерфейс не определен в терминах явного С1, но в более общих терминах, это дает гораздо большую гибкость .

Другие советы

Моя точка зрения заключается в том, что вы не должны изменять контракт, определенный API в документации. Если вам нужно новое поведение, вы должны либо: а) создать новый метод, который может вызываться клиентом, отражающим это новое поведение, либо б) обсудить с клиентом необходимость изменений и сообщить им об этом.

Это действительно может идти обоими путями, то, каков будет ваш подход, зависит от вас и ваших клиентов.

Это во многом зависит от того, что такое c2. Находится ли это в логических рамках уже существующего контракта? Если это так, вы удовлетворяете контракт, выбрасывая MyException. Если нет, то, возможно, вам нужно создать исключение нового типа.

Я должен отметить, что я не большой поклонник проверенных исключений. В конечном счете, принуждение кого-либо к исключению не обязательно делает его код лучше или безопаснее (на самом деле это может иметь противоположный эффект, поскольку они могут небрежно проглатывать ложные исключения).

Я бы сказал «нет», нет поломки API, если только MyException не является RuntimeException. Тогда это так.

В любом случае, я бы создал подкласс MyException для условия C2

И оба условия C1 и C2 должны быть "исключительными" ИМХО, я бы не стал выкидывать исключений

Это поломка. Применимо ли API к языковым конструкциям или просто задокументировано, не имеет значения.

Является ли эта поломка проблемой для клиентского кода, это другой вопрос. Возможно, вы исправляете дефект и вам необходимо таким образом покрыть корпус C2, чтобы исправить его. Исходя из этого, разработчики клиентского кода могут быть рады, что вы внесли это изменение (при условии, что они в настоящее время не работают над дефектом таким образом, который сломал бы перед лицом изменения!)

Я думаю, что проблема здесь в том, что вы сделали частью своего интерфейса особые условия реализации. Если "C1" условия были только частью вашей реализации, тогда вы могли бы просто создать новую реализацию, которая генерирует исключение для " C1 " или «C2»; не нарушая интерфейс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top