Когда вы вызываете конструктор, он всегда возвращает новый объект (если не выдается исключение). Статические фабричные методы или любая другая фабрика в этом отношении не всегда должны возвращать новый объект. Например, метод getInstance()
в традиционном шаблоне проектирования Singleton является фабричным методом, который всегда возвращает один и тот же объект. Есть случаи, когда иногда вы хотите сделать что-то подобное, будь то принудительное выполнение объекта может быть создано только один раз, или создание какого-либо пула объектов и т. Д. В общем, я думаю, что это дополнительная причина использования статические фабричные методы. Основная цель - создать псевдо-конструкторы с красивыми именами.
Вот (несколько глупый) пример использования статических фабричных методов для создания псевдо-конструкторов с хорошими именами. Рассмотрим этот класс:
class Person {
public Person(Role role) {
setRole(role);
}
...
}
Без статических фабричных методов вы можете сделать что-то вроде этого:
Person employee = new Person(Role.EMPLOYEE);
Person manager = new Person(Role.MANAGER);
Вместо этого вы можете создать статические фабричные методы:
class Person {
public static Person newEmployee() {
return new Person(Role.EMPLOYEE);
}
public static Person newManager() {
return new Person(Role.MANAGER);
}
private Person(Role role) {
setRole(role);
}
...
}
и вместо этого вы можете сделать что-то вроде этого:
Person employee = Person.newEmployee();
Person manager = Person.newManager();
Возможно, это не очень хороший пример, но рассмотрим более сложный конструктор или конструктор с менее описательным параметром. Иногда переход к заводскому методу делает код более понятным. Есть, конечно, недостатки ...
Что касается ограничения создания объекта, рассмотрим какое-то странное ограничение, будто никогда не может быть более одного генерального директора:
class Person {
private static Person singletonCEO = new Person(Role.CEO);
public static Person newCEO() {
return singletonCEO;
}
...
}
и как это будет создано:
Person ceo1 = Person.newCEO();
Person ceo2 = Person.newCEO();
assertThat(ceo1, is(ceo2)); // JUnit 4.x
Надеюсь, эти примеры помогут.