Лучший совет, который я видел в отношении исключений, состоит в том, чтобы генерировать исключение, если и только если альтернативой является невыполнение условия публикации или сохранение инварианта.
Этот совет заменяет неясное субъективное решение (это хорошая идея ) техническим, точным вопросом, основанным на проектных решениях (инвариантных и последующих условиях), которые вы уже должны были принять.
Конструкторы - это только частный, но не особый случай для такого совета. Таким образом, возникает вопрос, какие инварианты должен иметь класс? Сторонники отдельного метода инициализации, который будет вызываться после построения, предполагают, что у класса есть два или более режима работы , с режимом не готов после создания и, по крайней мере, один режим готовности , введенный после инициализации. Это является дополнительным осложнением, но приемлемо, если у класса все равно есть несколько режимов работы. Трудно понять, насколько полезно это усложнение, если бы у класса не было режимов работы.
Обратите внимание, что добавление set-up в отдельный метод инициализации не позволяет избежать возникновения исключений. Исключения, которые ваш конструктор мог выдать, теперь будут выбрасываться методом инициализации. Все полезные методы вашего класса должны генерировать исключения, если они вызваны для неинициализированного объекта.
Также обратите внимание, что избежать возможности создания исключений вашим конструктором проблематично, и во многих случаях невозможно во многих стандартных библиотеках. Это потому, что дизайнеры этих библиотек считают, что выбрасывать исключения из конструкторов - хорошая идея. В частности, любая операция, которая пытается получить не разделяемый или конечный ресурс (такой как выделение памяти), может завершиться неудачей, и этот сбой обычно указывается в ОО-языках и библиотеках, вызывая исключение.