Вы не нашли общий ответ на свой вопрос, потому что его нет. Это зависит от контекста, в котором используется построитель, или от деталей объекта, который строит.
Иногда имеет смысл возвращать объект по умолчанию, где все его члены инициализируются значениями по умолчанию. Но тогда этот объект по умолчанию должен быть действительным. Например. для создания объекта регистратора было бы правильным вернуть регистратор, который регистрирует на консоли с форматированием по умолчанию и уровнем журнала по умолчанию. Кто-то может мгновенно использовать его.
Но иногда чистый объект по умолчанию не имеет смысла. Создание полностью настроенного HTTP-клиента по умолчанию не имеет смысла, поскольку он не будет обеспечивать минимальное ожидаемое поведение, поскольку целевой URL может быть чем-то неожиданным. В этом случае вы можете написать конструктор для класса построителя, который принимает URL-адрес в качестве параметра (может быть, также некоторый объект данных), а затем предварительно сконфигурировать объект клиента со значениями по умолчанию (например, заголовок запроса по умолчанию, время ожидания по умолчанию, размер буфера по умолчанию и т. Д.) , Этот объект будет соответствовать минимальным ожиданиям использования. Каждый последующий вызов установщика будет перезаписывать значение по умолчанию, где каждый установщик должен проверять правильность аргументов, прежде чем принимать их.
Но вы всегда должны, когда это возможно, пытаться использовать значения по умолчанию для исключений. Когда для создания объекта требуется обязательная информация, сделайте ее общедоступной, поместив ее в конструктор. Таким образом, вы можете быть уверены, что ваш объект всегда находится в допустимом и полезном состоянии. В случае построителя HTTP-клиента вы можете вызвать исключение, если URL-адрес искажен, чтобы дать разработчику подсказку, что его код, который создает URL-адрес, может иметь недостатки. Возможно, прочитайте Лучшие практики для исключений .
Имея в виду решение написать конструкторы для сбора всех необходимых параметров (для которых нельзя установить полезные значения по умолчанию), ваш метод build()
finalize может и должен всегда и в любое время возвращать действительный и полезный объект. Это делает вашего строителя удобным. (В противном случае пользователь строителя будет вынужден прочитать документацию, чтобы узнать, какие сеттеры вызывать. Все знают, что вам не нравится писать документацию. Все знают, что вам не нравится прочитайте документацию перед использованием некоторых классов. Все чувствуют то же самое).