В ООП статические фабрики действительно не известны как шаблоны проектирования GOF.
Это методы, которые позволяют создавать и возвращать объекты.
Это имеет широкие намерения, такие как:
- сокрытие для клиентов некоторых деталей реализации, таких как возвращаемый объект времени выполнения.
- кэширование
- проксирование.
- облегчение использования API.
- замена конструкторов
Обратите внимание, что фабрика static
может не выполнять ничего из этого и просто использоваться как вспомогательный метод для создания объектов. Так что он может вообще не использовать функции ООП,
что не относится к заводским методам и шаблонам проектирования GOF в целом.
Фабрики не существует, если только Фабрика не считается усовершенствованной
Фабричный метод (слишком много входных параметров -> нужно определить несколько
методы createXXX)?
IHMO фабричный метод выглядит как вариант статической фабрики.
У него нет такого же намерения, и он гораздо более специализирован: он не абстрагирует / не скрывает создания объекта, но делегирует его некоторым фабричным подклассам.
Также обратите внимание, что фабричный метод может также полагаться на статические фабрики для создания своих объектов, в то время как обратное менее очевидно.
Поэтому я считаю, что этот шаблон GOF создания более структурирован, чем фабрика static
.
Пример для иллюстрации:
У Animal
могут быть дети. У нас есть несколько подклассов Animal
, и только подклассы Animal
должны знать, какой экземпляр возвращается для своих детей.
Здесь мы хотим использовать фабричный метод, поскольку мы разрешаем задачу создания экземпляров подклассам.
Вы могли бы так сделать:
public abstract class Animal {
public abstract ChildAnimal createChild(String name, LocalDate birthdate);
}
public class Dog extends Animal {
@Override
public ChildAnimal createChild(String name, LocalDate birthdate) {
return new LittleDog(name, birthdate);
}
}
public class Cat extends Animal {
@Override
public ChildAnimal createChild(String name, LocalDate birthdate) {
return new LittleCat(name, birthdate);
}
}
И так для ...
Хорошо, теперь предположим, что LittleCat
имеет несколько конструкторов.
Это не делает API простым.
Здесь мы могли бы использовать фабричные статические методы вместо конструкторов, чтобы прояснить ситуацию:
public class LittleCat implements ChildAnimal {
static LittleCat withNameAndBirthDateAndParents(String name, LocalDate birthdate, Cat dad, Cat mom) {
return new LittleCat("kitty", birthdate, dad, mom);
}
static LittleCat withNameAndBirthDate(String name, LocalDate birthdate) {
return new LittleCat(name, birthdate, null, null);
}
static LittleCat withNoInformation() {
return new LittleCat("kitty", LocalDate.now(), null, null);
}
private LittleCat(String name, LocalDate birthdate, Cat dad, Cat mom) {
// implementation
}
}
И теперь фабрика методов опирается на статическую фабрику:
public class Cat extends Animal {
@Override
public ChildAnimal createChild(String name, LocalDate birthdate) {
return LittleCat.withNameAndBirthDate(name, birthdate);
}
}