Почему объекты LocalDate, LocalTime и Stream используют фабричный метод() вместо конструктора?

Почему объекты LocalDate, LocalTime, Stream и т. д. используют фабричный метод of() вместо конструктора?

Я нашел объяснение, почему следует использовать фабричные методы вместо new здесь. Этот ответ дает ряд причин, но единственное, что имеет отношение к Java Date/Time API, это следующее:

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

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

Является ли это причиной того, что такие объекты, как LocalDate и LocalTime, создаются с помощью фабричного метода (т. е. LocalDate.of())? Есть ли другие причины?

Кроме того, объекты Stream изменяемы. Почему фабричный метод (Stream.of()) используется для создания Stream?


person Alex    schedule 17.07.2016    source источник
comment
Ответы на этот связанный вопрос о программистах также могут быть интересны.   -  person Hulk    schedule 18.07.2016


Ответы (2)


Почему фабричный метод (Stream.of()) используется для создания потока?

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

Из источника для Stream.of

/**
 * Returns a sequential {@code Stream} containing a single element.
 *
 * @param t the single element
 * @param <T> the type of stream elements
 * @return a singleton sequential stream
 */
public static<T> Stream<T> of(T t) {
    return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}

/**
 * Returns a sequential ordered stream whose elements are the specified values.
 *
 * @param <T> the type of stream elements
 * @param values the elements of the new stream
 * @return the new stream
 */
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

Примечание: эти методы вызывают другие фабричные методы.

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

person Peter Lawrey    schedule 17.07.2016
comment
Спасибо! Я принял этот ответ как наиболее популярный, но ответ Энди Тернера отвечает на вторую часть моего вопроса. - person Alex; 17.07.2016

+1 к ответу Питера.

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

Например, LocalDate имеет 6 статических фабричных методов (по крайней мере, здесь я не могу быть исчерпывающим):

  • of(int year, int/Month month, int dayOfMonth) (две перегрузки)
  • ofEpochDay(long epochDay)
  • ofYearDay(int year, int dayOfYear)
  • parse(CharSequence text)
  • parse(CharSequence text, DateTimeFormatter formatter)

Я думаю, что гораздо понятнее понять значения различных параметров, если использовать их как методы с отдельными именами, а не кучу конструкторов с очень похожими типами параметров; вы можете в значительной степени догадаться, какими должны быть параметры для фабричных методов, тогда как вам, возможно, придется прочитать Javadoc (шоковый ужас), если они были «безымянными» конструкторами.

По общему признанию, of является наименее понятным из этих имен — кому-то может понадобиться ofYearMonthDayOfMonth — однако я подозреваю, что это наиболее часто используемый фабричный метод, и он слишком загроможден, чтобы постоянно вводить это длинное имя.


Если вы еще не читали, пункт 1 книги Effective Java 2nd Edition посвящен тому, почему и когда следует предпочесть статические фабричные методы конструкторам. Преимущество «именованного конструктора», о котором я здесь упоминаю, на самом деле является первым преимуществом, которое выделяет Блох.

person Andy Turner    schedule 17.07.2016
comment
Спасибо! Теперь ясно. Мой пост содержит ссылку на выдержку/резюме из Effective Java. Я просто не мог понять, как эти принципы применялись в API Java SE 8. - person Alex; 17.07.2016
comment
Теперь у меня есть два ответа, и каждый отвечает на половину моего вопроса. Мне будет трудно выбрать один, чтобы принять ) - person Alex; 17.07.2016
comment
@Alex Peter явно не хватает очка или двух, помогите бедному маленькому мне ... ;p Не волнуйтесь, я уверен, что ни мы, ни мы не обидимся, если вы выберете другого. - person Andy Turner; 17.07.2016