Нужно ли нам когда-нибудь предпочитать конструкторы статическим фабричным методам? Если да, то когда? - PullRequest
12 голосов
/ 09 марта 2012

Я читал Эффективную Java от Джошуа Блоха и до сих пор он действительно оправдывает свою репутацию. Самый первый пункт убедительно доказывает статические фабричные методы над конструкторами . Настолько, что я начал сомневаться в обоснованности старых добрых конструкторов:).

Преимущества / недостатки из книги приведены ниже:

Преимущества:

  1. У них есть имена!
  2. У нас есть полный контроль над экземплярами (одиночные игры, производительность и т. Д.)
  3. Они могут возвращать подтип / интерфейс
  4. Компилятор может обеспечить вывод типа

Недостатки:

  1. Частные классы не могут быть разделены на подклассы
  2. Они не выделяются в документации, как конструкторы

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

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

Итак, мой вопрос в основном состоит из трех частей:

  1. Полезно ли всегда использовать статические фабричные методы по умолчанию над конструкторами?
  2. Разве когда-нибудь оправдано использование конструкторов?
  3. Почему объектно-ориентированные языки не обеспечивают поддержку языкового уровня для фабрик?

Примечание: Есть два похожих вопроса: Когда использовать конструктор и когда использовать метод getInstance () (статические фабричные методы)? и Создание объектов: Конструкторы или статические фабричные методы . Однако ответы либо просто предоставляют приведенный выше список, либо повторяют обоснование статических фабричных методов, о которых я уже знаю.

Ответы [ 4 ]

7 голосов
/ 09 марта 2012

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

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

Конструкторы - единственный способ установить конечные поля, которые, IMHO, предпочтительнее, чем не конечные.

Вы можете использовать конструкторы в подклассах.Вы не можете использовать статические фабрики для подкласса.

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

3 голосов
/ 09 марта 2012

У меня довольно сильное согласие с Джошем Блохом, и он делает это лучше, чем я, но вот несколько мест, где статические фабрики не подходят:

  • Когдавнедрение зависимости более разумно;Системы DI (конечно, Guice) имеют тенденцию вводить вещи через своих конструкторов.В частности, DI подходит, когда вы ожидаете, что параметры конструктора могут измениться в будущем.
  • Когда вы специально собираетесь, чтобы люди писали подклассы, и вы предоставляете скелет для их реализации.
3 голосов
/ 09 марта 2012

Мне нравится комментарий к одному из похожих вопросов, которые вы выделили:

(о том, как решить, следует ли использовать метод фабрики над конструктором),

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

Для меня это означает, что оправдано для использования конструктора, где фабричный метод не требуется. Без какой-либо необходимости в фабрике, это просто усложняет выполнение кода («какой именно подкласс возвращается здесь?»)

0 голосов
/ 10 марта 2012

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

Скучные вещи.Давайте сделаем что-то более веселое и интеллектуальное испытание ...

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

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