Throw/do-not-throw исключение на основе параметра - почему это не хорошая идея?

Из того, что я могу сказать, класс Cheltuieli реализует очень маленькое подмножество того, что уже сделано в классе std::string - но это неполно, так что если вы сделаете:

Cheltuieli orig("something");
Cheltuieli cpy = orig;

оба orig и cpy будут иметь член name, указывающий на один и тот же адрес из-за конструктора копирования по умолчанию. Читайте о Правило три / пять / ноль .

Точно так же класс Repo, кажется, реализует что-то близкое к std::vector. Я предлагаю вам не начинать возиться с необработанными указателями, а использовать для этого стандартные классы. Вы могли бы даже сделать псевдонимы для них:

using Cheltuieli = std::string;
using Repo = std::vector;

Используется так:

Cheltuieli a = "pizza";
Repo n;
n.push_back(a);
n.push_back(a);

for(auto& cheltuieli : n) {
    std::cout << cheltuieli << "\n";
}

7
задан cbp 9 March 2009 в 00:57
поделиться

7 ответов

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

Это было бы намного лучше и более читаемым, чтобы иметь 2 API в этом случае.

Uri ParseUriOrThrow(string value);

bool TryParseUri(string value, out Uri uri);

В этом случае на 100% ясно, что делают эти API.

Статья о том, почему булевские переменные плохи как параметры: http://blogs.msdn.com/jaredpar/archive/2007/01/23/boolean-parameters.aspx

9
ответ дан 6 December 2019 в 15:32
поделиться

Обычно лучше выбрать один механизм обработки ошибок и придерживаться его последовательно. Разрешение этого вида триггерного кода не может действительно улучшить жизнь разработчиков.

В вышеупомянутом примере, что происходит при парсинге сбоев и throwOnError, ложь? Теперь пользователь должен предположить, знает ли ПУСТОЙ УКАЗАТЕЛЬ при попытке возвращаться, или бог...

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

3
ответ дан 6 December 2019 в 15:32
поделиться

Это довольно противно с точки зрения удобочитаемости. Разработчики склонны ожидать, что каждый метод выдаст исключение, и если они захотят проигнорировать исключение, то они поймают его сами. С подходом 'булева флага' каждый метод должен реализовать это семантическое запрещение исключения.

Однако я думаю, что статья MSDN строго относится к флагам 'throwOnError'. В этих случаях любой ошибка проигнорирована в самом методе (плохо, поскольку это скрыто), или некоторый объект пустого указателя/ошибки возвращается (плохо, потому что Вы не используете исключения для обработки ошибки, которая непоследовательна и оно подверженный ошибкам).

Принимая во внимание, что Ваш пример кажется прекрасным мне. Исключение указывает на отказ метода выполнить его обязанность - нет никакого возвращаемого значения. Однако флаг 'allowEmpty' изменяет семантику метода - поэтому, что было бы исключением ('Пустое значение'), теперь ожидается и законен. Плюс при выдаче исключения Вы легко не смогли бы возвратить данные конфигурации. Таким образом, это кажется OK в этом случае.

1
ответ дан 6 December 2019 в 15:32
поделиться

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

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

1
ответ дан 6 December 2019 в 15:32
поделиться

Другим примером в соответствии с этим мог быть набор методов TryParse на некоторых типах значения

bool DateTime.TryParse(string text, out DateTime)

0
ответ дан 6 December 2019 в 15:32
поделиться

Наличие donTThrowException параметра побеждает смысл исключений (на любом языке). Если код вызова хочет иметь:

public static void Main()
{
        FileStream myFile = File.Open("NonExistent.txt", FileMode.Open, FileAccess.Read);
}

им рады в (C# даже не имеет контролируемых исключительных ситуаций). В Java то же самое было бы выполнено с:

public static void main(String[] args) throws FileNotFoundException
{
        FileInputStream fs = new FileInputStream("NonExistent.txt");
}

Так или иначе это - задание вызывающей стороны, чтобы решить, как обработать (или не) исключение, не вызываемый.

0
ответ дан 6 December 2019 в 15:32
поделиться

В связанном со статьей существует примечание, что Исключения не должны использоваться для потока управления - который, кажется, подразумевается в примере questsions. Исключения должны отразить отказ уровня Метода. Иметь подпись, что нормально бросать Ошибку, кажется, что дизайн не продуман.

Книга Jeffrey Richters, на которую CLR через C# указывает - "Вы, должна выдать исключение, когда метод не может выполнить свою задачу, как обозначено его именем".

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

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

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

0
ответ дан 6 December 2019 в 15:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: