Обеспечивая исключение непроверенное "фантик" интерфейсы API с проверено исключения


Недавно у меня была дискуссия на форуме из API, потому что они изменили исключение из зарегистрированного в unchecked. Я полагал, что это должно быть проверено, потому что это можно восстановить. Аргументы "другой стороны" были многословие и занудство попробовать/поймать или бросает.

Если бы это был чисто теоретический вопрос, я был бы прав, но я согласен, что на практике это иногда нудно писать все эти попробовать/ловит только ради повторной генерации исключения непроверенные, или лесозаготовки.

Итак, идея пришла мне в голову, и интересно, будет ли она жизнеспособна. Я проиллюстрирую с простой код:

public interface Foo {
    String foo() throws Exception;
}

public interface EasyFoo extends Foo {
    String foo();
}

Эти два интерфейса, которые определяют один и тот же метод (и это должно выполняться по наследству), но "легкая" версия не определяет бросая проверенные исключения. Затем приходят 2 реализации по умолчанию:

public class FooImpl implements Foo {

    @Override
    public String foo() throws Exception {
        return "foo";
    }
}

public class EasyFooImpl implements EasyFoo {

    Foo foo;

    public EasyFooImpl(Foo foo) {
        this.foo = foo;
    }

    @Override
    public String foo() {
        try {
            return foo.foo();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

Последние делегаты бывший, оборачивая все исключения в исключения на этапе выполнения.

И, наконец, фабрика:

public class FooFactory {
    public static Foo createFoo() {
        return new FooImpl();
    }

    public static EasyFoo createEasyFoo() {
        return new EasyFooImpl(new FooImpl());
    }
}

Преимущества:

  • пользователь API может выбрать, как ему нравится использовать реализацию. Если он не намерен ничего делать с проверено исключения, он может использовать "легкий" вариант
  • вам работать только один интерфейс. 2-й такой же, и вы просто должны добавить методы, что у вас в основном один.
  • пользователь может использовать EasyFoo в местах, где ФОО требуется:

    EasyFoo foo = FooFactory.createEasyFoo();
    helper.doSomething(foo); // which is public void doSomething(Foo foo);
    

Достаточно Экарт - вопрос, Является ли это жизнеспособным решением, которое может снизить уровень детализации при сохранении хорошей стороны проверяемых исключений?



3299
9
задан 8 февраля 2011 в 05:02 Источник Поделиться
Комментарии
4 ответа

Просто примите тот факт, что исключение непроверенное и двигаться дальше.

Индустрия движется от проверенных исключений: C++ не имел их, на C# решили не следовать Java в этом месте, и новейшие фреймворки для Java используют непроверенные исключения.

Лицо его, проверил исключения-отличная идея, которая не работает на практике.

В результате, что вы попробовать в коде, никогда не пройдет ни один комментарий код я буду частью.

4
ответ дан 9 февраля 2011 в 12:02 Источник Поделиться

Ок, я собираюсь предположить, что это действительно исключительный случай, что крайне маловероятно. Это не похоже на Java.SQL, который генерирует исключение при открытии соединения, которое может произойти очень легко и должны быть обработаны, возвращая значение null.

Если есть люди, которые хотят это исключение непроверенное, они должны написать собственную обертку для него, ИМО. Если вы хотите его в библиотеке, хотя, я бы сделал это точно так же, как для интерфейсов. Непроверенной версии не зависит от проверяемого пробную реализацию, так что вы только когда-нибудь понадобится один фантик EasyFooImpl.

Я хотел бы поинтересоваться дизайн библиотеки, если я когда-либо видел. Checked или unchecked, то лучше, чтобы избежать исключений. Есть только две уважительные причины я вижу как "исключения-достойны":


  • Где неизвестная операция оставляет код в неизвестных/недопустимое состояние. Это должно невозвратными код, который бросает исключение.

  • Где невозможно вернуть недопустимом состоянии, такие как значение null или 0. Пример, который приходит на ум, это целое число.метод Parse(). Вы можете не возвращать значение null; она требует инт. И вы не можете вернуть 0 или НАН , потому что находится в допустимом обратном наборе метод. Исключение, самое чистое, наиболее удобном для чтения формате вы можете сигнал того, что строка является unparsable в целое число.

1
ответ дан 8 февраля 2011 в 09:02 Источник Поделиться

Просто добавить в разговор:

ИМХО проверенное исключение включены по причине. Метод с умеренная вероятность отказа должна бросить проверенное исключение. например, IO классы зависит от способности устройств ввода-вывода, который может быть не доступен в то время и таким образом бросить проверенное исключение, исключение IOException. Благо объявления IOException как проверить, что Java обеспечивает предоставление обработку ошибок или альтернативное решение. Это не применяется в случае исключения производных из RuntimeException. ИМХО это исполнение призывает программистов для написания надежного кода, который лучше, чем не иметь дополнительную throws пункт.

1
ответ дан 12 февраля 2011 в 04:02 Источник Поделиться

Если я должен был сделать что-нибудь подобное, я бы просто использовать Java-приложений.яз.отразить.Прокси и создания оболочек на лету. Вам проверить, если методы foo и EasyFoo являются правильно подобранный и запретить EasyFoo осущ (оба интерфейса должны иметь одинаковые сигнатуры методов, но EasyFoo, не объявленные исключения). В конце концов у вас есть библиотека многоразовые делать грязные вещи. Вызов через прокси-сервер будет работать медленнее, но кого это волнует.

Поэтому в основном вам нужен класс генерирует прокси и одним назначенным исключение для обертывания. Вы должны обернуть исключения, которые лишь декларируются.

В целом код, хотя для меня синтетический сахар. Ты всегда можешь переехать ж/ вместо этого бросает декларации. Даже можно, наверное, изменяя компилятор не очень осуществимо, но во время выполнения проверки не волнует деклараций исключение.

0
ответ дан 4 марта 2011 в 10:03 Источник Поделиться