Я не знаю, есть ли документы в IntelliJ как таковые. Тем не менее, модель довольно легко объяснить.
В коде Java есть шаблон для использования статических фабричных методов (это специализация шаблона метода «Банды четырех фабрикантов»), часто в соответствии с (в переводе на Scala-ish):
object Foo {
def barInstance(args...): Bar = ???
}
Основным преимуществом этого является то, что фабрика контролирует создание объектов, в частности:
конкретный класс времени выполнения для создания экземпляра, возможно, основанный на аргументах фабрики. Например, универсальные неизменяемые коллекции в Scala имеют фабричные методы, которые могут создавать оптимизированные небольшие коллекции, если они созданы с достаточно небольшим количеством содержимого. Примером этого является последовательность длиной 1, которая может быть реализована практически без издержек с одним полем, ссылающимся на объект, и поиском, который проверяет, равно ли смещение 0, и либо выбрасывает, либо возвращает свое единственное поле.
создан ли экземпляр. Можно кешировать аргументы фабрике и запоминать или «хэшконсить» созданные объекты, или создавать самые распространенные экземпляры и выдавать их повторно.
Еще одним преимуществом является то, что фабрика - это функция, а new
- оператор, который позволяет обходить фабрику:
class Foo(x: Int)
object Foo {
def instance(x: Int) = new Foo(x)
}
Seq(1, 2, 3).map(x => Foo(x)) // results in Seq(Foo(1), Foo(2), Foo(3))
В Scala это сочетается с тем фактом, что язык позволяет любому объекту, который определяет метод apply
, использоваться синтаксически как функция (даже если он не расширяет Function
, что позволило бы объекту быть переданным, как если бы это была функция) и с "объектом-компаньоном" к классу (который включает в себя вещи, которые в Java были бы static
в классе), чтобы получить что-то вроде:
class Foo(constructor_args...)
object Foo {
def apply(args...): Foo = ???
}
Что можно использовать как:
Foo(...)
Для case class
компилятор Scala автоматически генерирует объект-компаньон с определенным поведением, одним из которых является apply
с теми же аргументами, что и конструктор (другие поведения включают выполнение контракта hashCode
и equals
а также метод unapply
для сопоставления с образцом).