API Java break - PullRequest
       7

API Java break

6 голосов
/ 24 июня 2009

У меня есть следующий 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, клиентское приложение все равно будет работать, но в зависимости от того, как клиенты перехватят исключение, поведение приложения может сильно измениться.

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

Ответы [ 6 ]

7 голосов
/ 24 июня 2009

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

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

6 голосов
/ 24 июня 2009

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

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

1 голос
/ 24 июня 2009

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

1 голос
/ 24 июня 2009

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

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

1 голос
/ 24 июня 2009

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

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

И оба условия С1 и С2 должны быть "исключительными" ИМХО, я бы не стал привычкой бросать исключения

1 голос
/ 24 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...