Почему многие языки относятся к объектам Exception как к первоклассным гражданам? - PullRequest
2 голосов
/ 29 октября 2009

Когда мы получаем объекты, которые на самом деле являются исключениями, мы можем делать с ними все, что мы можем делать с обычными объектами на нашем языке. Мы можем передать их в качестве аргумента, мы можем сохранить их в некоторой коллекции и, что самое худшее, мы можем вернуть их в результате методов!

Так что для кого-то есть возможность написать вонючий код, подобный этому:

public Exception doSomethingCritical()
{
    Exception error = null;

    try
    {
        ...
    }
    catch (Exception e)
    {
        // maybe at least here is the logging of the error if we are lucky
        error = e;
    }
    return error;
}

Итак, вопрос в том, почему концепция объекта-исключения является первоклассным гражданином во многих ОО-языках? Может быть, будет лучше, если у нас есть только ограниченные конструкции в языке, которые разрешены для объектов исключений (например, throw).

Ответы [ 7 ]

6 голосов
/ 29 октября 2009

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

  • Разрешение подклассов исключений. Это неоценимо для обработки исключений, так как код, работающий с исключениями, может сузить область их действия и работать только с исключениями, с которыми он знает, как иметь дело. Я бы даже сказал, что любая неглобальная подпрограмма обработки исключений, которая ловит только «Исключение», вероятно, делает это неправильно.
  • Передача данных вместе с исключениями. Исключения не очень полезны, если единственная вещь, которую вы знаете в логике перехвата, - это исключение. Трассировки стека, сообщения и даже пользовательские данные для определенных типов исключений неоценимы для выявления и устранения проблемы, вызвавшей исключение.
  • Создание процедур обработки ошибок, которые сами используют ООП. Если исключения не могут быть переданы как объекты, вы не можете, например, иметь библиотеку, которая работает с исключениями - ну, по крайней мере, не очень хорошо написанную.

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

2 голосов
/ 29 октября 2009

Я никогда не видел того примера, который вы использовали. И я не понимаю, как не позволение людям возвращать исключения будет иметь большое значение для концептуально плохого кода - сравните

public int doSomethingCritical()
{
    int error = 0;

    try
    {
        ...
    }
    catch (Exception e)
    {
        // maybe at least here is the logging of the error if we are lucky
        error = E_SOMETHINGBAD;
    }
    return error;
}

Принимая во внимание, что если вы создаете новый тип «вещи», который будет использоваться для исключений, которые не совпадают с объектами, существует недостаток дизайна и обучения.

1 голос
/ 29 октября 2009

Мое мнение.

Я думаю, что вы путаете две разные вещи: исключение и бросок исключения.

Бросок исключений - это внеполосный процесс, который позволяет вам бросать объект через предпочтительный боковой канал. Этот объект может быть перехвачен и обработан с помощью механизма перехвата исключений.

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

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

1 голос
/ 29 октября 2009

Я не понимаю, почему мне нельзя разрешать передавать и возвращать исключения как обычные параметры метода. Что если бы я писал библиотеку обработки исключений? Что если бы я писал утверждение модульного теста, в котором сравнивались исключения?

1 голос
/ 29 октября 2009

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

0 голосов
/ 29 октября 2009

Я не уверен, что приведенный вами пример является достаточно веским аргументом для исключения исключений в качестве объектов. В конце концов, вы МОЖЕТЕ делать все виды "вонючих" или "плохих" вещей во время программирования. Однако именно поэтому мы хотим хороших программистов. Просто потому, что я могу сделать что-то вроде:

def get_total
   return nil
end

определенно не означает, что я не должен допускать nil как экземпляр объекта!

0 голосов
/ 29 октября 2009

Потому что жизнь намного проще. Среди прочего, это означает, что объект исключения может содержать информацию, которую программа может использовать для исправления исключительной ситуации (возможно, с вмешательством человека).

Абенд так 1960-х годов.

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