Почему абстрактный Factory имеет дело с семействами и Factory Метод с генерированием одного объекта?
Из того, что я прочитал, абстрактный шаблон factory обычно относится к созданию нескольких объектов, все из которых связаны с одним и тем же семейством, а шаблон метода factory относится к созданию одного объекта.
Рассмотрим следующий пример, который отражает эти проблемы:
// Factory Method (base class) allowing for creation of families of objects
public class BasePizzaCreator{
abstract ISauce CreateSauce();
abstract IToppings CreateToppings();
abstract ICrust CreateCrust();
}
// Abstract Factory (interface) defining contract to create a single object
public interface IPizzaFactory{
abstract IPizza CreatePizza();
}
Очевидно, что вы можете использовать их таким образом - но является ли это нарушением духа шаблонов? Если да, то почему?
Что я действительно хочу здесь понять: Почему Abstract factory лучший подход для создания семейств связанных объектов, а метод factory - лучший подход к созданию единого объекта?
Ответы
Ответ 1
В приведенных примерах BasePizzaCreator
является абстрактной фабрикой, но IPizzaFactory
- это не какой-либо шаблон проектирования GoF (хотя его иногда называют простой фабрикой).
Что касается того, почему Абстрактная Фабрика имеет дело с семействами продуктов, тогда как Фабричный Метод имеет дело с одним продуктом: это просто, как их определил GoF. В книге GoF упоминается, что наиболее распространенным способом реализации абстрактной фабрики является использование нескольких фабричных методов; но я не видел этого на практике. С точки зрения клиента, абстрактная фабрика может быть предпочтительнее, потому что клиенты вызывают ее через составление/делегирование, в отличие от фабричного метода, который требует, чтобы клиенты наследовали этот метод.
Наконец, обратите внимание, что "Абстрактная фабрика против фабричного метода" является второй по популярности темой шаблонов проектирования при переполнении стека. К сожалению, есть также много (высоко поднятой) дезинформации, поэтому, если есть сомнения, всегда обращайтесь к книге.
Ответ 2
Это разница в намерении этих двух шаблонов.
FactoryMethod
: Определите интерфейс для создания объекта, но пусть подклассы определяют, какой класс необходимо создать. FactoryMethod
позволяет классу отложить экземпляр к подклассам.
AbstractFactory
: предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
AbstractFactory
классы часто реализуются с помощью FactoryMethods
, но они могут быть реализованы даже с помощью Prototypes
Обычно начинайте дизайн с FactoryMethod
и может развиваться по отношению к другим шаблонам создания, таким как AbstractFactory
, Prototype
или Builder
Я тоже согласен с ответом @jaco0646 относительно преимущества использования AbstractFactory
(использует делегирование/состав) от клиента вместо использования FactoryMethod
(который основан на наследовании)
Относительно вашего последнего запроса:
Почему Abstract Factory лучший подход для создания семейств связанных объектов, а метод Factory - лучший подход к созданию единого объекта?
Да. Оба они предназначены для разных целей, как указано в намерении.
AbstractFactory имеет преимущество в возврате одного из продуктов из семейства.
Преимущество FactoryMethod: он может возвращать один и тот же экземпляр несколько раз или может возвращать подкласс, а не объект этого точного типа.
Обратитесь к этой sourcemaking для лучшего понимания этих шаблонов.