Вопрос
Что считается "Лучшей практикой" - и почему - обработки ошибок в конструкторе?.
"Лучшая практика" может быть цитатой от Schwartz, или 50% модулей CPAN используют ее и т.д.; но я доволен хорошо аргументированным мнением любого, даже если он объясняет, почему общая наилучшая практика - это не лучший подход.
Что касается моего собственного мнения по этой теме (в течение многих лет я рассказывал о разработке программного обеспечения на Perl), я видел три основных подхода к обработке ошибок в модуле perl (по моему мнению, от лучших до худших):
-
Построить объект, установить недопустимый флаг (обычно "
is_valid
" ). Часто в сочетании с установкой сообщения об ошибке с помощью обработки ошибок класса.Плюсы:
-
Позволяет выполнять стандартные (по сравнению с другими вызовами) обработку ошибок, поскольку позволяет использовать вызовы типа
$obj->errors()
после неудачного конструктора, как и после любого другого вызова метода. -
Позволяет передавать дополнительную информацию (например, > 1 ошибка, предупреждения и т.д.)
-
Позволяет использовать легкую функциональность "redo" / "fixme". Другими словами, если объект, который был сконструирован, очень тяжелый, со многими сложными атрибутами, которые на 100% всегда в порядке, и единственная причина, по которой это не действительный, потому что кто-то ввел неверную дату, вы можете просто сделать "
$obj->setDate()
" вместо накладных расходов на повторное выполнение всего конструктора. Этот шаблон не всегда необходим, но может быть чрезвычайно полезным в правильном дизайне.
Минусы: Нет, о которых я знаю.
-
-
Вернуть "
undef
".Минусы: невозможно достичь ни одного из преимуществ первого решения (сообщения об ошибках для объектов за пределами глобальных переменных и облегченная "фиксированная" возможность для тяжелых объектов).
-
Убейте внутри конструктора. Вне некоторых очень узких краевых случаев я лично считаю это ужасным выбором для слишком многих причин перечислять на полях этого вопроса.
-
ОБНОВЛЕНИЕ. Чтобы быть ясным, я считаю, что решение (в противном случае очень достойное и отличное решение) имеет очень простой конструктор, который не может вообще терпеть неудачу, и тяжелый метод инициализации, где вся проверка ошибок происходит быть просто подмножеством в любом случае # 1 (если инициализатор устанавливает флаги ошибок) или случай №3 (если инициализатор умирает) для целей этого вопроса. Очевидно, выбирая такую конструкцию, вы автоматически отклоняете опцию № 2.