В чем принципиальная разница между фабричным и абстрактным шаблонами? [закрыто]

483

В чем принципиальная разница между фабричными и абстрактными фабричными моделями?

user366312
источник
11
На мой взгляд, качество ответов в Разницах между Абстрактным Фабричным шаблоном и Фабричным методом намного лучше, чем здесь.
KurzedMetal
1
Ключевое отличие состоит в том, что Factory Method использует наследование (например, косвенное направление - вертикальное createThing()), а Abstract Factory - композицию (например, косвенное направление getFactory().createThing())
David James,
1
Вопрос не в том, что думают некоторые из его ответчиков. Не пропустите ответ Тенгиза , который определяет три разных термина Фабрика, Абстрактная Фабрика и Фабричный метод.
Дейв Швейсгут

Ответы:

412

С рисунком Factory, вы производите экземпляров реализаций ( Apple, Banana, Cherryи т.д.) конкретного интерфейса - скажем, IFruit.

С помощью шаблона «Абстрактная фабрика» вы предоставляете возможность каждому создать собственную фабрику. Это позволяет вашему складу быть или IFruitFactoryили IJuiceFactoryбез, не требуя, чтобы ваш склад знал что-нибудь о фруктах или соках.

Джон Феминелла
источник
5
@ SPI Я думаю, вы меня не так поняли; Сама Фабрика не нуждается в реализации IFruit- она ​​создает вещи, которые реализуют IFruit. Конечно, не нужно создавать экземпляры вещей, которые реализуют определенный интерфейс, но это, вероятно, запах кода, если у вас есть Фабрика, которая производит вещи, которые абсолютно не связаны друг с другом.
Джон Феминелла
75
Завод, который производит фабрики. Нам нужно идти глубже ...
Павел Аннеков
11
Никогда не слышал ничего более неправильного, чем это. Что бы вы назвали фабрикой, которая производит интерфейсы абстрактных фабрик (IAbstractFactory)? - Ах, я вижу, это будет AbstractAbstractFactory ...
Tengiz
3
@joaquin Например, когда вам нужно иметь фабрику IFruitFactory. И, как я уже упоминал, это совершенно неверно, и это просто результат путаницы в шаблонах. Мой ответ ниже проясняет: есть шаблон «Абстрактная фабрика», затем шаблон «Метод фабрики», и есть люди, которые думают, что «Абстрактная фабрика» означает фабрику других фабрик. Фабрика - это просто общий термин, используемый для обозначения любого из существующих шаблонов. Смотрите мой ответ ниже для более подробной информации, если это необходимо.
Тенгиз
9
Этот ответ просто неправильно! Согласно этой книге GoF , абстрактная фабрика - это фабричный объект, который реализует фабричный интерфейс, так что конкретная фабрика может быть заменена на другой подкласс. Это не имеет ничего общего с созданием фабрик. Пожалуйста, удалите этот ответ, он вводит в заблуждение и сбивает с толку людей!
Лии
142

Источник этой информации взят из: http://java.dzone.com/news/intro-design-patterns-abstract

Абстрактная фабрика против фабричного метода

Методы абстрактной фабрики реализованы как фабричные методы. И абстрактный шаблон фабрики, и шаблон метода фабрики отделяют клиентскую систему от реальных классов реализации через абстрактные типы и фабрики. Фабричный метод создает объекты с помощью наследования, а Абстрактная фабрика создает объекты с помощью композиции.

Шаблон Abstract Factory состоит из AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct и клиента.

Как реализовать

Абстрактный шаблон фабрики может быть реализован с использованием шаблона фабричного метода, шаблона прототипа или шаблона Singleton. Объект ConcreteFactory может быть реализован как Singleton, поскольку необходим только один экземпляр объекта ConcreteFactory.

Шаблон Factory Method - это упрощенная версия шаблона Abstract Factory. Шаблон Factory Method отвечает за создание продуктов, принадлежащих одному семейству, а шаблон Abstract Factory - для нескольких семейств продуктов.

Фабричный метод использует интерфейсы и абстрактные классы для отделения клиента от класса генератора и конечных продуктов. Абстрактная фабрика имеет генератор, который является контейнером для нескольких фабричных методов, а также интерфейсы, отделяющие клиента от генератора и продуктов.

Когда использовать шаблон фабричного метода

Используйте шаблон Factory Method, когда необходимо отделить клиента от конкретного продукта, который он использует. Используйте фабричный метод, чтобы снять с клиента ответственность за создание и настройку экземпляров продукта.

Когда использовать абстрактный шаблон фабрики

Используйте шаблон Abstract Factory, когда клиенты должны быть отделены от классов продуктов. Особенно полезно для настройки и модификации программы. Шаблон Абстрактная фабрика также может навязывать ограничения относительно того, какие классы должны использоваться с другими. Может быть много работы по созданию новых бетонных заводов.

Примеры:

Абстрактная фабрика Пример 1

Эта спецификация для дисков для приготовления различных видов макаронных изделий в устройстве для изготовления макаронных изделий является абстрактной фабрикой, а каждый конкретный диск - фабрикой. все фабрики (диски для изготовления макаронных изделий) наследуют свои свойства от абстрактной фабрики. Каждый отдельный диск содержит информацию о том, как создать макароны, а производитель макаронных изделий - нет.

Абстрактный Фабричный Пример 2:

Штамповочное оборудование соответствует абстрактной фабрике, так как это интерфейс для операций, которые создают абстрактные объекты продукта. Матрицы соответствуют бетонному заводу, поскольку они создают конкретный продукт. Каждая категория деталей (капот, дверь и т. Д.) Соответствует абстрактному произведению. Конкретные детали (то есть дверь со стороны водителя на 99 кулачков) соответствуют конкретным изделиям.

Пример фабричного метода:

Компания по производству игрушек соответствует Создателю, поскольку она может использовать фабрику для создания объектов товара. Подразделение компании по производству игрушек, которое производит игрушку определенного типа (лошадь или автомобиль), соответствует ConcreteCreator.

Судхакар Калмари
источник
6
Спасибо за объяснение абстрактной фабрики и фабричного метода. Я не понял, где мы используем композицию в абстрактной фабрике для создания объектов и где мы используем наследование в фабричном методе. Будет очень полезно, если вы опубликуете некоторый код для их объяснения. Большое спасибо. жду вашего кода. Еще раз спасибо.
Харша
то же самое и здесь, было бы гораздо яснее, если бы подходы к составлению и наследованию были показаны на кратком примере (исходный код).
Аакаш
Пример кода @ sourcemaking.com/design_patterns/abstract_factory
pramodc84
пример композиции: открытый класс Client {AbstractProduct product; АннотацияПродуктыАксессуары для аксессуаров; общедоступный клиент (фабрика AbstractFactory) {AbstractProduct product = factory.createProduct (); } public void run () {product.print (); аксессуары = product.getAccessories (); }}
Асим Гаффар
Можно ли в коде определить, какой из этих двух шаблонов использовался?
Чернокнижник
98

Фабричный шаблон: Фабрика производит IProduct-реализации

Абстрактная модель фабрики: фабрика-фабрика производит фабрики, которые в свою очередь производят продукцию IP :)

[Обновление в соответствии с комментариями]
То, что я написал ранее, по крайней мере, неверно в Википедии . Абстрактная фабрика - это просто фабричный интерфейс. С его помощью вы можете переключать свои фабрики во время выполнения, чтобы разрешить разные фабрики в разных контекстах. Примерами могут быть разные фабрики для разных ОС, провайдеры SQL, промежуточные драйверы и т. Д.

cwap
источник
4
Ницца! Правильно ли говорить, что Абстрактная фабрика - это набор фабричных методов?
Чернокнижник
2
Я думаю, это было бы правильно, но это также упустило бы смысл :). Не аналогичным примером может быть FileFactory, который имеет такие методы, как CreateBitmapFile () или CreateTextFile (). Теперь вы передадите ссылку на эту фабрику в какой-то сервис. Но что произойдет, если вы захотите проверить свой сервис? Вам придется создать интерфейс IFileFactory, чтобы запретить доступ к файловой системе. Теперь, в реальном мире, у вас, вероятно, будет структура DI / IoC, которая будет создавать экземпляры IFileFactories в зависимости от ваших потребностей. В этом случае структура IoC будет служить абстрактной фабрикой.
cwap
5
Если я правильно понимаю, этот ответ, кажется, подразумевает, что Абстрактная Фабрика всегда производит дальнейшие IFactories, которые в свою очередь могут использоваться для создания IP-продуктов. Мне кажется, что презентация в GoF не подтверждает это и фактически противоречит этому: экземпляр Abstract Factory непосредственно производит IProducts самостоятельно. Другими словами, абстрактная фабрика GoF не является (или, скорее, не обязана ) «фабрикой-фабрикой».
SSJ_GZ
1
Определение абстрактного фабричного шаблона неверно. Абстрактная фабрика содержит один или несколько фабричных методов, каждый из которых создает экземпляр из одного и того же семейства объектов (не путать с иерархией объектов). Хотя абстрактная фабрика может быть фабрикой фабрик, она не обязательно должна быть фабрикой. Это производитель сопутствующих товаров.
GiddyUpHorsey
1
Этот ответ просто неправильно! Согласно этой книге GoF , абстрактная фабрика - это фабричный объект, который реализует фабричный интерфейс, так что конкретная фабрика может быть заменена на другой подкласс. Это не имеет ничего общего с созданием фабрик. Пожалуйста, удалите этот ответ, он вводит в заблуждение и сбивает с толку людей!
Лии
42

Абстрактная фабричная картина

  • Предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.

  • Шаблон Abstract Factory очень похож на шаблон Factory Method. Одно из различий между ними состоит в том, что с шаблоном Abstract Factory класс делегирует ответственность за создание экземпляра объекта другому объекту через композицию, тогда как шаблон Factory Method использует наследование и опирается на подкласс для обработки требуемого экземпляра объекта.

  • На самом деле, делегированный объект часто использует фабричные методы для выполнения экземпляров!

Фабричный образец

  • Фабричные образцы - примеры творческих образцов

  • Образцы творчества абстрагируют процесс создания объекта. Они скрывают, как создаются объекты, и помогают сделать систему в целом независимой от того, как создаются и создаются ее объекты.

  • Шаблоны создания классов фокусируются на использовании наследования для определения объекта, который должен быть создан. Factory Method

  • Шаблоны создания объекта ориентированы на делегирование экземпляра другому объекту. Абстрактная фабрика

Справка: Фабрика против Абстрактной Фабрики

Сайед Тайяб Али
источник
3
ссылка не работает
mkobit
39

Заводской метод: вас есть фабрика, которая создает объекты, производные от определенного базового класса

Абстрактная фабрика: у вас есть фабрика, которая создает другие фабрики , а эти фабрики в свою очередь создают объекты, производные от базовых классов. Вы делаете это, потому что вы часто не просто хотите создать отдельный объект (как в методе Factory), а хотите создать коллекцию связанных объектов.

Крейг Шварц
источник
6
Это дубликат принятого ответа и в равной степени неверный.
jaco0646
36

Абстрактная фабрика - это интерфейс для создания связанных объектов, а фабричный метод - это метод. Абстрактная фабрика реализуется фабричным методом.

введите описание изображения здесь

Попытка
источник
36

Основное отличие:

Фабрика: создает объекты, не раскрывая логику реализации клиенту.

Фабричный метод : определите интерфейс для создания объекта, но пусть подклассы решают, какой класс создать. Метод Factory позволяет классу откладывать создание экземпляров для подклассов

Абстрактная Фабрика : предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.

Шаблон AbstractFactory использует композицию, чтобы делегировать ответственность за создание объекта другому классу, в то время как метод Factory шаблон использует наследование и опирается на производный класс или подкласс для создания объекта.

Из статей о дизайне :

Заводская диаграмма классов:

введите описание изображения здесь

Пример: StaticFactory

 public class ShapeFactory {

   //use getShape method to get object of type shape 
   public static Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }     
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();

      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();

      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }

      return null;
   }
}

Нестатическая фабрика, реализующая пример FactoryMethod, доступна в этом посте:

Шаблоны проектирования: метод фабрики против фабрики против абстрактной фабрики

Когда использовать: Клиенту просто нужен класс, и ему все равно, какую конкретную реализацию он получает.

Заводской метод класса дигарам:

введите описание изображения здесь

Когда использовать: Клиент не знает, какие конкретные классы необходимо будет создать во время выполнения, но просто хочет получить класс, который будет выполнять эту работу.

Абстрактная фабричная диаграмма классов из dzone

введите описание изображения здесь

Когда использовать: когда вашей системе необходимо создать несколько семейств продуктов или вы хотите предоставить библиотеку продуктов без раскрытия деталей реализации.

Примеры исходного кода в вышеприведенных статьях очень хороши для четкого понимания концепций.

Связанный вопрос SE с примером кода:

Заводская модель. Когда использовать фабричные методы?

Отличия:

  1. Абстрактные фабричные классы часто реализуются с помощью фабричных методов, но они также могут быть реализованы с использованием Prototype
  2. Проекты начинаются с использования Factory Method (менее сложный, более настраиваемый, подклассы разрастаются) и переходят к другим шаблонам творчества (более гибким, более сложным), где требуется большая гибкость.
  3. Заводские методы обычно вызываются в шаблонных методах.

Другие полезные статьи:

factory_method от создания источника

abstract_factory от создания источника

абстрактный-фабричный-дизайн-шаблон из журнала

Равиндра Бабу
источник
21

Пример / сценарий для абстрактной фабрики

Я живу в месте, где в сезон дождей идет дождь, зимой - снег, а летом жарко и солнечно. Мне нужна другая одежда, чтобы защитить себя от стихии. Для этого я иду в магазин рядом с моим домом и прошу одежду / предметы, чтобы защитить себя. Хранитель магазина дает мне соответствующий предмет в соответствии с окружающей средой и глубиной моего кармана. Предметы, которые он мне дает, имеют такой же уровень качества и ценовой категории. Поскольку он знает о моих стандартах, ему легко это сделать. Но когда богатый парень с другой стороны улицы предъявляет те же требования, он получает дорогой фирменный товар. Одна заметная вещь - все предметы, которые он дает мне, дополняют друг друга с точки зрения качества, стандарта и стоимости. Можно сказать, что они идут друг с другом. То же самое и с вещами, которые получает этот богатый парень.

Итак, глядя на вышеприведенный сценарий, я теперь оцениваю эффективность продавца. Я могу заменить этого лавочника абстрактным магазином. Предметы, которые мы получаем с абстрактными предметами, и я, и богатые как перспективные клиенты. Все, что нам нужно, это продукт / предмет, который соответствует нашим потребностям.

Теперь я легко вижу себя, рассматривая интернет-магазин, который предоставляет множество услуг своим многочисленным клиентам. Каждый клиент принадлежит к одной из трех групп. Когда пользователь премиум-группы открывает сайт, он получает отличный пользовательский интерфейс, настраиваемую панель рекламы, больше опций в меню и т. Д. Этот же набор функций представлен золотому пользователю, но функциональность в меню меньше, реклама в основном релевантна, и немного менее эргономичный интерфейс. Последний - мой тип пользователя, пользователь «свободной группы». Я просто достаточно обслужен, чтобы не обижаться. Пользовательский интерфейс - это минимум, рекламные объявления настолько далеки от отслеживания, что я не знаю, что из этого выйдет, наконец, в меню есть только выход из системы.

Если бы у меня была возможность создать что-то похожее на этот сайт, я бы определенно рассмотрел шаблон Abstract Factory Pattern

Абстрактные продукты: Панель рекламы, Меню, Пользовательский интерфейс художника.
Абстрактная фабрика: пользовательский опыт интернет-магазина.
Конкретная фабрика: опыт премиум-пользователя, удобство работы с золотом, общее удобство пользователя.

moajiz
источник
Хорошие сценарии AbstractFactory, но вы так и не ответили на вопрос, в чем разница между фабрикой и абстрактной фабрикой.
Аделин
20

Многие могут удивиться, но этот вопрос неверен . Если вы слышите этот вопрос во время собеседования, вам нужно помочь интервьюеру понять, в чем путаница.

Начнем с того, что нет конкретного шаблона, который называется просто «Фабрика». Существует шаблон, который называется «Абстрактная фабрика», и существует шаблон, который называется «Метод фабрики».

Итак, что же значит «Фабрика»? одно из следующего (все может считаться правильным, в зависимости от объема ссылки):

  • Некоторые люди используют его как псевдоним (ярлык) для « Абстрактной фабрики ».
  • Некоторые люди используют его как псевдоним (ярлык) для « Factory Method ».
  • Некоторые люди используют это как более общее название для всех фабричных / творческих моделей. Например, «Абстрактная фабрика» и «Фабричный метод» являются фабриками.

И, к сожалению , многие люди используют «Фабрика» для обозначения другого вида фабрики, которая создает фабрику или фабрики (или их интерфейсы). Основываясь на их теории:

Продукт реализует IProduct, который создается Factory, который реализует IFactory, который создается AbstractFactory.

Чтобы понять, насколько это глупо, давайте продолжим наше уравнение:

AbstractFactory реализует IAbstractFactory, который создается ... AbstractAbstractFactory ???

Я надеюсь, что вы видите смысл. Не смущайтесь, и, пожалуйста, не изобретайте вещи, которые не существуют по причине.

-

PS : Фабрика для продуктов - это AbstractFactory, а Фабрика для абстрактных фабрик - еще один пример AbstractFactory.

Тенгиз
источник
Как можно отличить AbstractFactory, которая создает другие AbstractFactory, от AbstractFactory, которая создает конкретные объекты? GenericAbstractFactory? Или AbstractFactoryFactory?
Андрей
В шаблонах дизайна такого нет. Оба они являются экземплярами шаблона AbstractFactory. Итак, одна AbstractFactory создает конкретные объекты, а другая AbstractFactory создает фабрики (которые снова являются AbstractFactory).
Тенгиз
Конечно. Так как же назвать эти классы, которые делают разные вещи? Потому что создание других фабрик и создание других (простых) объектов - это разные вещи. Мне не нужны шаблоны, мне нужен читаемый код.
Андрей
3
Читаемый код - это намерение раскрыть код. При именовании классов не следует упоминать слишком много шаблонов, если в этом нет особой необходимости. например, если у вас есть абстрактная фабрика, которая создает различные транспорты, возможно, назовите ее TransportCreator или TransportFactory, или, возможно, даже TransportManufacturer. И потом, если у вас есть фабрика этих фабрик, вы можете назвать это как угодно - кто бы ни открывал новых производителей. Может быть, это может быть управление производителем? в основном, называйте вещи так, как их называет ваш бизнес, а НЕ основываясь на том, какие шаблоны они реализуют.
Тенгиз
16
//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{    
   public Dough createDough(); //Will return you family of Dough
   public Clam createClam();   //Will return you family of Clam
   public Sauce createSauce(); //Will return you family of Sauce
}

class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{

   @Override
   public Dough createDough(){
      //create the concrete dough instance that NY uses
      return doughInstance;
   }

   //override other methods
} 

Определения учебника уже предоставлены другими ответами. Я думал, что приведу пример этого тоже.

Итак, здесь PizzaIngredientsFactoryесть абстрактная фабрика, так как она предоставляет методы для создания семейства связанных продуктов.

Обратите внимание, что каждый метод в абстрактной фабрике сам по себе является фабричным методом . Like createDough()сам по себе является фабричным методом, чьи конкретные реализации будут предоставляться подклассами like NYPizzaIngredientsFactory. Таким образом, используя это, каждое другое местоположение может создавать экземпляры конкретных ингредиентов, которые принадлежат их местоположению.

Заводской метод

Предоставляет пример конкретной реализации

В примере:
- createDough()- предоставляет конкретную реализацию для теста. Так что это фабричный метод

Абстрактная Фабрика

Предоставляет интерфейс для создания семейства связанных объектов

В примере:
- PizzaIngredientsFactoryэто абстрактная фабрика , поскольку это позволяет создать связанный набор объектов , таких как Dough, Clams, Sauce. Для создания каждого семейства объектов предусмотрен фабричный метод.

Пример из головы Первые шаблоны дизайна

Нарендра Патхай
источник
5

У меня есть несколько моментов, которые я могу внести в ответ Джона следующим образом:

Абстрактная фабрика это фабрика заводов!

С «Factory Method» (потому что только «Фабрика» неоднозначно), вы производите реализации ( Lemon, Orangeи т.д.) конкретного интерфейса - скажем, IFruit. Эту Фабрику можно назвать CitricFruitFactory.

Но теперь вы хотите создать другие виды фруктов, которые не может создать CitricFruitFactory. Может быть, код CitricFruitFactoryне будет иметь смысла, если вы создадите Strawberryв нем (клубника не лимонный фрукт!).

Таким образом , вы можете создать новый завод под названием , RedFruitFactoryкоторая производит Strawberry, Raspberryи т.д.

Как сказал Джон Феминелла: «Используя шаблон Abstract Factory, вы создаете реализации определенного интерфейса Factory - например, IFruitFactoryкаждый из них знает, как создавать различные виды фруктов».

Это реализации IFruitFactoryявляются CitricFruitFactoryи RedFruitFactory!

fabriciorissetto
источник
4

Мои источники: StackOverflow, tutorialspoint.com, programmers.stackexchange.comи CodeProject.com.


Factory Method(также называется Factory) для развязки клиента Interfaceреализации. Для примера у нас есть Shapeинтерфейс с двумя Circleи Squareреализациями. Мы определили класс фабрики с методом фабрики с параметром определителя, таким как Typeи новая связанная реализация Shapeинтерфейса.


Abstract Factoryсодержит несколько фабричных методов или фабричный интерфейс несколькими фабричными реализациями. Для следующего примера выше у нас есть Colorинтерфейс с двумя Redи Yellowреализациями. Мы должны определить ShapeColorFactoryинтерфейс с двумя RedCircleFactoryи YellowSquareFactory. Следующий код для объяснения этой концепции:

interface ShapeColorFactory
{
    public Shape getShape();
    public Color getColor();
}

class RedCircleFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Circle();
    }

    @Override
    public Color getColor() {
        return new Red();
    }
}
class YellowSquareFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Square();
    }

    @Override
    public Color getColor() {
        return new Yellow();
    }
} 

Здесь разница между FactoryMethodа AbstractFactory. Factory Methodа просто вернуть конкретный класс интерфейса, ноAbstract Factory вернуть factory of factory. Другими словами, Abstract Factoryвозвращаются различные сочетания из серии интерфейсов.


Я надеюсь, что мое объяснение полезно.

Сэм
источник
3

Основное различие в этих фабриках заключается в том, когда вы хотите делать с фабриками, и когда вы хотите их использовать.

Иногда, когда вы делаете IOC (инверсия управления, например, инжекция в конструктор), вы знаете, что можете создавать твердые объекты. Как упоминалось в примере выше фруктов, если вы готовы создавать объекты из фруктов, вы можете использовать простой фабричный шаблон .

Но часто вы не хотите создавать твердые объекты, они появятся позже в потоке программы. Но конфигурация говорит вам, какую фабрику вы хотите использовать при запуске, вместо создания объектов вы можете передавать фабрики, производные от общего класса фабрики, конструктору в IOC.

Итак, я думаю, что это также о времени существования и создания объекта.

Махендра Венгурлекар
источник
3

Оба Factory Methodи Abstract Factoryдержат клиентов отделенными от конкретных типов. Оба создают объекты, но Factoryметод использует наследование, тогда какAbstract Factory использует композицию.

Factory MethodНаследуется в подклассах для создания конкретных объектов (продукции) , тогда какAbstract Factory предоставляют интерфейс для создания семейства связанных продуктов, а подклассы этого интерфейса определяют, как создавать связанные продукты.

Затем эти подклассы при создании экземпляра передаются в классы продукта, где он используется как абстрактный тип. Связанные продукты в Abstract Factoryчасто реализуются с использованием Factory Method.

Акаш Аггарвал
источник
3

Расширяя ответ Джона Феминеллы:

Apple, Banana, CherryИнвентарь FruitFactoryи что есть метод , называемый , Createкоторый несет ответственность создания компании Apple или банана или вишни. Вы сделали, с вашим Factoryметодом.

Теперь вы хотите Createспециальный салат из своих фруктов, и вот вам ваша абстрактная фабрика . Abstract Factory знает, как создать свой особенный салат из яблок, бананов и вишни.

public class Apple implements Fruit, FruitFactory {
    public Fruit Create() {
        // Apple creation logic goes here
    }
}

public class Banana implements Fruit, FruitFactory {
    public Fruit Create() {
        // Banana creation logic goes here
    }
}

public class Cherry implements Fruit, FruitFactory {
    public Fruit Create() {
        // Cherry creation logic goes here
    }
}

public class SpecialSalad implements Salad, SaladFactory {
    public static Salad Create(FruitFactory[] fruits) {
        // loop through the factory and create the fruits.
        // then you're ready to cut and slice your fruits 
        // to create your special salad.
    }
}
Абдул Муним
источник
2

По определению мы можем вытянуть различия двух:

Фабрика: интерфейс используется для создания объекта, но подкласс решает, какой класс создать. Создание объекта выполняется тогда, когда это требуется.

Абстрактная фабрика: шаблон Абстрактная фабрика действует как суперфабрика, которая создает другие фабрики. В шаблоне Abstract Factory интерфейс отвечает за создание набора связанных объектов или зависимых объектов без указания их конкретных классов.

Таким образом, в приведенных выше определениях мы можем подчеркнуть конкретное различие. то есть шаблон Factory отвечает за создание объектов, а Abstract Factory отвечает за создание набора связанных объектов; очевидно, как через интерфейс.

Заводская модель:

public interface IFactory{
  void VehicleType(string n);
 }

 public class Scooter : IFactory{
  public void VehicleType(string n){
   Console.WriteLine("Vehicle type: " + n);
  }
 }

 public class Bike : IFactory{
  public void VehicleType(string n) {
  Console.WriteLine("Vehicle type: " + n);
  }
 }

 public interface IVehicleFactory{
  IFactory GetVehicleType(string Vehicle);
 }

 public class ConcreteVehicleFactory : IVehicleFactory{
 public IFactory GetVehicleType(string Vehicle){
   switch (Vehicle){
    case "Scooter":
     return new Scooter();
    case "Bike":
     return new Bike();
    default:
    return new Scooter();
  }
 }

 class Program{
  static void Main(string[] args){
   IVehicleFactory factory = new ConcreteVehicleFactory();
   IFactory scooter = factory.GetVehicleType("Scooter");
   scooter.VehicleType("Scooter");

   IFactory bike = factory.GetVehicleType("Bike");
   bike.VehicleType("Bike");

   Console.ReadKey();
 }
}

Абстрактная фабричная картина:

interface IVehicleFactory{
 IBike GetBike();
 IScooter GetScooter();
}

class HondaFactory : IVehicleFactory{
     public IBike GetBike(){
            return new FZS();
     }
     public IScooter GetScooter(){
            return new FZscooter();
     }
 }
class HeroFactory: IVehicleFactory{
      public IBike GetBike(){
            return new Pulsur();
     }
      public IScooter GetScooter(){
            return new PulsurScooter();
     }
}

interface IBike
    {
        string Name();
    }
interface IScooter
    {
        string Name();
    }

class FZS:IBike{
   public string Name(){
     return "FZS";
   }
}
class Pulsur:IBike{
   public string Name(){
     return "Pulsur";
   }
}

class FZscooter:IScooter {
  public string Name(){
     return "FZscooter";
   }
}

class PulsurScooter:IScooter{
  public string Name(){
     return "PulsurScooter";
   }
}

enum MANUFACTURERS
{
    HONDA,
    HERO
}

class VehicleTypeCheck{
        IBike bike;
        IScooter scooter;
        IVehicleFactory factory;
        MANUFACTURERS manu;

        public VehicleTypeCheck(MANUFACTURERS m){
            manu = m;
        }

        public void CheckProducts()
        {
            switch (manu){
                case MANUFACTURERS.HONDA:
                    factory = new HondaFactory();
                    break;
                case MANUFACTURERS.HERO:
                    factory = new HeroFactory();
                    break;
            }

      Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " +      factory.GetScooter().Name());
        }
  }

class Program
    {
        static void Main(string[] args)
        {
            VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
            chk.CheckProducts();

            chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
            chk.CheckProducts();

            Console.Read();
        }
    }
Rashedul.Rubel
источник
1

Проверьте здесь: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm кажется, что метод Factory использует определенный класс (не абстрактный) в качестве базового класса, в то время как Abstract factory использует для этого абстрактный класс. Также, если использовать интерфейс вместо абстрактного класса, результатом будет другая реализация шаблона Абстрактной фабрики.

: D

hackus
источник
1

Abstract Factory - шаблон для создания различных типов интерфейсов. Предположим, у вас есть проект, который требует, чтобы вы анализировали различные типы CSV-файлов, содержащих информацию о количестве, цене и товаре, например, некоторые содержат данные о фруктах, другие о шоколадных конфетах, а затем после анализа вам нужно обновить эту информацию в соответствующей базе данных, чтобы теперь вы могли иметь одна абстрактная фабрика возвращает вам парсер и фабрику модификаторов, а затем эта фабрика парсеров может возвращать вам объект синтаксического анализатора шоколада, объект анализатора фруктов и т. д., и аналогично фабрика модификаторов может возвращать объект модификатора шоколада, объект модификатора фруктов и т. д.

Капил
источник
1

Я думаю, что мы можем понять разницу между этими двумя, увидев пример кода Java8:

  interface Something{}

  interface OneWhoCanProvideSomething {
     Something getSomething();
  }

  interface OneWhoCanProvideCreatorsOfSomething{
     OneWhoCanProvideSomething getCreator();
  }


public class AbstractFactoryExample {

    public static void main(String[] args) {
        //I need something
        //Let's create one
        Something something = new Something() {};

        //Or ask someone (FACTORY pattern)
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;

        //Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
        OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;

        //Same thing, but you don't need to write you own interfaces
        Supplier<Something> supplierOfSomething = () -> null;
        Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
    }

}

Теперь вопрос в том, какой способ создания следует использовать и почему: Первый способ (без шаблона, просто простой конструктор): создание самостоятельно - не очень хорошая идея, вы должны выполнить всю работу, и ваш клиентский код привязан к конкретная реализация.

Второй способ (с использованием шаблона Factory): предоставляет вам преимущество, заключающееся в том, что вы можете передать любой тип реализации, который может предоставить другой тип чего-либо на основе некоторого условия (возможно, параметра, передаваемого в метод создания).

Третий способ (использование шаблона Abstract Factory): это дает вам больше гибкости. Вы можете найти разные типы создателей чего-либо на основании какого-либо условия (возможно, переданного параметра).

Обратите внимание, что вы всегда можете обойтись без паттерна Factory, комбинируя вместе два условия (что немного увеличивает сложность кода и связывание), я думаю, поэтому мы редко видим реальные случаи использования паттерна Abstract Factory.

Сатьендра Кумар
источник