Позвольте мне начать с реализации java шаблона фабричного метода:
interface Product {
}
class ConcreteProduct implements Product {
}
abstract class Creator {
abstract Product createProduct();
final void usage() {
final Product product = createProduct();
System.out.println(product);
}
}
final class ConcreteCreator extends Creator {
@Override
Product createProduct() {
return new ConcreteProduct();
}
}
1) Для первого вопроса давайте рассмотрим предложение
Другие шаблоны проектирования требуютновые классы, тогда как Factory Method требует только новой операции.
Учитывая новую реализацию Product
, шаблон фабричного метода требует нового подкласса, так что это не может быть тем случаем, о котором идет речь в предложении.Вместо этого, контекст здесь, вероятно, заключается в том, что в методе Creator.usage
требуется новая зависимость, например, от interface Item
.В этом случае новые классы не требуются, мы просто добавляем метод abstract Item createItem()
к существующему Создателю и его подклассам.
Сравните это с шаблоном прототипа.Во-первых, давайте изменим пример кода, чтобы можно было применить шаблон прототипа:
interface ProductPrototype extends Product {
ProductPrototype prototypeCopy();
}
class ConcreteProductPrototype implements ProductPrototype, Product {
@Override
public ProductPrototype prototypeCopy() {
return new ConcreteProductPrototype();
}
}
abstract class Creator {
final static boolean usePrototype = false;
abstract Product createProduct();
final void usage(final ProductPrototype prototype) {
final Product product;
if (usePrototype) {
product = prototype.prototypeCopy();
} else {
product = createProduct();
}
System.out.println(product);
}
}
Теперь, если добавлен новый Item
, который мы хотим использовать в нашем создателе, нам также нужно добавить новые классыItemPrototype
и подкласс для каждой конкретной реализации Item
.
2) Для второго вопроса
Люди часто используют фабричный метод в качестве стандартного способа создания объектов, но этоне требуется, когда [...] создание экземпляра происходит в операции, которую подклассы могут легко переопределить, например в операции инициализации.
давайте рассмотрим пример кода:
interface Product {
}
class ConcreteProduct implements Product {
}
class DefaultProduct implements Product {
}
abstract class Creator {
Product product;
void initialize() {
product = new DefaultProduct();
}
}
final class ConcreteCreator extends Creator {
@Override
void initialize() {
product = new ConcreteProduct();
}
}
Заводской метод не требуется, поскольку метод (легко) переопределяется в подклассе.Обратите внимание, что в первоначальном примере фабричный метод необходим, потому что мы не хотим переопределять метод usage
в каждом подклассе (то есть он может не быть легко переопределенным).