У чому полягає основна відмінність між фабричними та абстрактними моделями дизайну заводу? [зачинено]


483

У чому полягає основна відмінність фабричних та абстрактних заводських моделей?


11
На мою думку, якість відповідей у відмінностях між абстрактним фабричним малюнком та фабричним методом набагато краща, ніж тут.
KurzedMetal

1
Ключова відмінність полягає в тому, що заводський метод використовує успадкування (непряме, наприклад, вертикальне createThing()), а абстрактний завод використовує композицію (непрямість, наприклад, горизонтальність getFactory().createThing())
Девід Джеймс

1
Це питання не те, про що думають деякі його відповіді. Не пропустіть відповідь Тенгіза , який визначає три чіткі терміни Фабрика, Абстрактна фабрика та Фабричний метод.
Дейв Швайсгут

Відповіді:


412

З малюнком Factory, ви робите примірників реалізацій ( Apple, Banana, Cherryі т.д.) конкретного інтерфейсу - скажімо, IFruit.

За допомогою абстрактного фабричного шаблону ви надаєте спосіб кожному забезпечити власну фабрику. Це дозволяє вашому складу бути або IFruitFactoryабо IJuiceFactory, не вимагаючи від вашого складу нічого знати про фрукти чи соки.


5
@SPI Я думаю, ти мене неправильно розумієш; Саму Фабрику не потрібно впроваджувати IFruit- вона створює речі, які реалізує IFruit. Звичайно, не потрібно створювати екземпляри речей, що реалізують певний інтерфейс, але це, мабуть, запах коду, якщо у вас є Фабрика, яка виробляє речі, які абсолютно не пов'язані один з одним.
Джон Фемінелла

75
Фабрика, яка виробляє фабрики. Нам потрібно піти глибше ...
Павло Аннеков

11
Ніколи не чув нічого більш неправильного, ніж це. Як би ви назвали фабрику, яка виробляє інтерфейси абстрактних заводів (IAb абстрактFactory)? - Ага, я бачу, це було б AbstractAbriefFactory ...
Тенгіз

3
@joaquin Наприклад, коли вам потрібно мати завод IFruitFactory. І як я вже згадував, це абсолютно неправильно, і це лише результат плутанини щодо зразків. Моя відповідь нижче пояснює - це абстрактний заводський зразок, потім заводський метод, а потім є розгублені люди, які думають, що абстрактна фабрика означає завод інших заводів. Фабрика - лише загальний термін, що використовується для позначення будь-якого з існуючих зразків. Дивіться мою відповідь нижче для отримання більш детальної інформації, якщо це потрібно.
Тенгіз

9
Ця відповідь це просто невірно! Згідно з цією книгою GoF , абстрактна фабрика - це заводський об’єкт, який реалізує заводський інтерфейс, щоб бетонну фабрику можна було замінити на інший підклас. Це не має нічого спільного зі створенням фабрик. Видаліть цю відповідь, вона вводить в оману та заплутує людей!
Лій

142

Джерело цієї інформації взято з: http://java.dzone.com/news/intro-design-patterns-ab Abstract

Анотація заводу проти заводського методу

Методи абстрактної фабрики реалізовані як фабричні методи. Як абстрактний заводський візерунок, так і заводський метод методу відокремлює клієнтську систему від реальних класів впровадження через абстрактні типи та заводи. Фабричний метод створює об'єкти у спадок, де Абстрактна фабрика створює об'єкти через композицію.

Абстрактний заводський візерунок складається з абстрактного фабричного, бетонного фактурного, абстрактного продукту, конкретного продукту та клієнта.

Як реалізувати

Абстрактний заводський візерунок може бути реалізований за допомогою заводського методу, шаблону прототипу або одинарного малюнка. Об'єкт ConcreteFactory може бути реалізований як Singleton, оскільки потрібен лише один екземпляр об'єкта ConcreteFactory.

Заводський метод шаблону - це спрощена версія абстрактного фабричного шаблону. Фабричний шаблон моделі відповідає за створення продуктів, що належать до однієї родини, тоді як абстрактний заводський зразок стосується кількох сімейств продуктів.

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

Коли використовувати заводський метод шаблону

Використовуйте шаблон заводських методів, коли є необхідність від'єднати клієнта від певного продукту, який він використовує. Використовуйте заводський метод, щоб звільнити клієнта від відповідальності за створення та налаштування примірників продукту.

Коли використовувати абстрактний заводський візерунок

Використовуйте абстрактний заводський шаблон, коли клієнти повинні бути відірвані від класів продуктів. Особливо корисно для налаштування та модифікації програми. Анотація «Заводська модель» також може застосовувати обмеження щодо того, які класи повинні використовуватися з іншими. Зробити нові бетонні заводи може бути багато роботи.

Приклади:

Приклад 1 абстрактного заводу

Ця специфікація для дисків для приготування різних видів макаронних виробів у виробнику макаронних виробів - це «Фабрика абстрактних», а кожен конкретний диск - «Фабрика». всі заводи (диски для виготовлення макаронних виробів) успадковують свої властивості від абстрактної Фабрики. Кожен окремий диск містить інформацію про те, як створити пасту, а виробник пасти - ні.

Приклад 2 абстрактного заводу:

Обладнання для штампування відповідає «Фабриці абстрактних», оскільки це інтерфейс для операцій, що створюють абстрактні об’єкти продукту. Штампи відповідають Бетонному заводу, оскільки вони створюють бетонний виріб. Кожна категорія деталей (капюшон, двері тощо) відповідає абстрактному твору. Конкретні деталі (тобто, бічні двері для водія на 99 кемрі) відповідають конкретним виробам.

Приклад заводського методу:

Компанія іграшок відповідає Творцю, оскільки вона може використовувати фабрику для створення предметів товару. Підрозділ іграшкової компанії, яка виробляє конкретний тип іграшки (коня чи машини), відповідає ConcreteCreator.


6
Дякуємо за пояснення абстрактного фабричного та фабричного методу. Я не розумів, де ми використовуємо композицію на абстрактній фабриці для створення об'єктів і де ми використовуємо спадщину фабричним методом. Буде дуже корисно, якщо ви опублікуєте якийсь код, щоб пояснити це. Дуже дякую. чекаю вашого коду. Знову дякую.
Харша

тут же було б набагато зрозуміліше, якби підходи до складу та успадкування показані коротким прикладом (вихідний код).
Аакаш


Приклад композиції: Клієнт публічного класу {продукт AbstractProduct; Аксесуари для аксесуарів публічний клієнт (FactoryFactory factory) {AbstractProduct product = factory.createProduct (); } публічний недійсний запуск () {product.print (); аксесуари = product.getAccessories (); }}
Асим Гаффар

Чи можливо в коді виявити, який із цих двох шаблонів використовувався?
Warlock

98

Фабрична схема: Фабрика виробляє реалізацію IProduct

Абстрактний заводський зразок: фабрика-фабрика виробляє IFactories, яка, в свою чергу, виробляє IProducts :)

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


4
Приємно! Чи правильно сказати, що абстрактна фабрика - це набір заводських методів?
Warlock

2
Я думаю, що це було б правильно, але це також пропустило б справу :) Не аналогічним прикладом може бути FileFactory, який мав такі методи, як CreateBitmapFile () або CreateTextFile (). Тепер ви передасте посилання на цю фабрику в якусь послугу. Але що буде, як тільки ви захочете перевірити свою послугу? Вам доведеться створити інтерфейс IFileFactory, щоб висміяти доступ до файлової системи. Тепер у реальному світі ви, мабуть, матимете рамку DI / IoC, яка б створила IFileFactories залежно від ваших потреб. У цьому випадку рамка IoC була б фабрикою абстрактних.
обмін

5
Якщо я правильно розумію, ця відповідь, мабуть, означає, що абстрактний завод завжди виробляє подальші IFactories, які в свою чергу можуть бути використані для створення IProducts. Представлення в GoF не здається мені, що це підтверджує, і насправді це суперечить: екземпляр абстрактного заводу безпосередньо виробляє самі IProducts. Іншими словами, абстрактна фабрика GoF не є (точніше, не повинна бути ) "фабрикою-заводом".
SSJ_GZ

1
Визначення абстрактного заводського зразка невірно. Абстрактна фабрика містить один або кілька заводських методів, кожен з яких створює екземпляр з одного і того ж сімейства об'єктів (не плутати з ієрархією об'єктів). Хоча абстрактна фабрика може бути фабрикою фабрик, вона не повинна бути такою. Це виробник супутніх товарів.
GiddyUpHorsey

1
Ця відповідь це просто невірно! Згідно з цією книгою GoF , абстрактна фабрика - це заводський об’єкт, який реалізує заводський інтерфейс, щоб бетонну фабрику можна було замінити на інший підклас. Це не має нічого спільного зі створенням фабрик. Видаліть цю відповідь, вона вводить в оману та заплутує людей!
Лій

42

Абстрактний заводський візерунок

  • Забезпечте інтерфейс для створення сімей пов’язаних або залежних об'єктів, не вказуючи їх конкретні класи.

  • Абстрактний заводський візерунок дуже схожий на заводський метод. Одна відмінність між ними полягає в тому, що за абстрактним заводським зразком клас делегує відповідальність за інстанціювання об'єкта іншому об'єкту за допомогою композиції, тоді як шаблон методу Factory використовує успадкування і покладається на підклас для обробки потрібного об'єкта.

  • Власне, делегований об'єкт часто використовує заводські методи для виконання інстанції!

Фабричний візерунок

  • Фабричні візерунки - приклади креативних моделей

  • Творчі візерунки абстрагують процес інстанціїзації об'єкта. Вони приховують, як створюються об'єкти, і допомагають зробити загальну систему незалежною від того, як створюються та складаються її об'єкти.

  • Шаблони творчих процесів класу зосереджуються на використанні спадщини для визначення об'єкта, який підлягає інстанції Фабричний метод

  • Об'єктні креативні візерунки фокусуються на делегуванні інстанції на інший об'єкт абстрактного заводу

Довідка: Фабрика проти абстрактної фабрики


3
посилання померло
mkobit

39

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

Анотація заводу: у вас є завод, який створює інші фабрики , а ці фабрики, в свою чергу, створюють об'єкти, отримані з базових класів. Ви робите це, тому що часто не просто хочеться створити єдиний об'єкт (як при Фабричному методі), а потрібно створити колекцію пов'язаних об'єктів.


6
Це дублікат прийнятої відповіді, і однаково неправильно.
jaco0646

36

Анотація заводу - це інтерфейс для створення пов'язаних об'єктів, але заводський метод - це метод. Абстрактна фабрика реалізована фабричним методом.

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


36

Основна різниця:

Фабрика: створює об'єкти, не піддаючи клієнту логіку ідентифікації.

Фабричний метод : Визначте інтерфейс для створення об’єкта, але нехай підкласи вирішують, який клас інстанціювати. Фабричний метод дозволяє відкладати екземпляр класу для підкласів

Анотація заводу : надає інтерфейс для створення сімей пов’язаних або залежних об'єктів без зазначення їх конкретних класів.

Шаблон 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. Абстрактні фабричні класи часто реалізовуються за допомогою заводських методів, але вони також можуть бути реалізовані за допомогою прототипу
  2. Дизайн починається з заводського методу (менш складний, більш налаштований, підкласи розповсюджуються) та розвивається до інших креативних моделей (більш гнучких, складніших), де потрібна більша гнучкість.
  3. Заводські методи зазвичай викликаються у межах методів шаблонів.

Інші корисні статті:

factory_method з створення джерела

Abstract_factory від створення джерела

абстрактно-фабрика-дизайн-візерунок від journaldev


21

Приклад / сценарій для абстрактних заводів

Я живу там, де у дощовий сезон йде дощ, взимку снігу, влітку жарко і сонячно. Мені потрібен різний вид одягу, щоб захистити себе від стихій. Для цього я заходжу в магазин біля свого будинку і прошу одяг / предмети, щоб захистити себе. Власник магазину дає мені відповідний предмет відповідно до середовища та глибини кишені. Елементи, які він мені дає, мають однаковий рівень якості та цінового діапазону. Оскільки він знає мої стандарти, йому це легко зробити. Але коли багатий хлопець з усієї вулиці висуває ті самі вимоги, він отримує дорогий, фірмовий предмет. Одне помітне - всі предмети, які він мені дає, доповнюють один одного за рівнем якості, стандарту та вартості. Можна сказати, що вони йдуть один з одним. Те саме стосується предметів, які отримує цей багатий хлопець.

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

Тепер я легко бачу себе, розглядаючи Інтернет-магазин, який надає набір послуг своїм численним клієнтам. Кожен клієнт належить до однієї з трьох груп. Коли користувач преміум-групи відкриває сайт, він отримує чудовий інтерфейс користувача, високоіндивідуальну панель реклами, більше опцій у меню тощо. Цей самий набір функцій представлений користувачеві із золота, але функціональність у меню менше, реклама в основному сприйнятлива, і трохи менш егрономічний інтерфейс користувача. Останнє - це мій тип користувача, користувач «вільної групи». Мені просто подано достатньо, щоб я не образився. Користувальницький інтерфейс - це мінімальний мінімум, реклама настільки відсторонена, що я не знаю, що в ньому входить, нарешті, меню лише вийшло.

Якщо я отримаю можливість створити щось на зразок цього веб-сайту, я б точно розглядав абстрактний заводський зразок.

Абстрактні продукти: Панель реклами, меню, художник інтерфейсу.
Абстрактна фабрика: Досвід користувачів веб-магазину
Створити завод: Преміальний досвід користувачів, Золотий досвід користувачів, Загальний досвід користувачів.


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

20

Можливо, багато людей почуватимуться здивованими, але це питання неправильне . Якщо ви чуєте це питання під час інтерв'ю, вам потрібно допомогти інтерв'юеру зрозуміти, де знаходиться плутанина.

Почнемо з того, що не існує конкретного малюнка, який називається просто «Фабричний». Існує шаблон, який називається "Абстрактний завод", і є шаблон, який називається "Фабричний метод".

Отже, що означає "Фабрика"? одне з наступних (все можна вважати правильним, залежно від обсягу посилання):

  • Деякі люди використовують його як псевдонім (ярлик) для " Абстрактного заводу ".
  • Деякі люди використовують його як псевдонім (ярлик) для " Фабричного методу ".
  • Деякі люди використовують його як більш загальну назву для всіх фабричних / рекламних моделей. Наприклад, "Абстрактний завод" і "Фабричний метод" - це Заводи.

І, на жаль , багато людей використовують "Фабрику" для позначення іншого виду фабрики, що створює фабрику або фабрики (або їх інтерфейси). Виходячи з їх теорії:

Продукт реалізує IProduct, який створений Factory, який реалізує IFactory, який створюється AbstractFactory.

Щоб зрозуміти, наскільки це нерозумно, продовжимо наше рівняння:

AbstractFactory реалізує IAbpositeFactory, який створюється ... AbstractAb абстрактFactory ???

Сподіваюся, ви бачите сенс. Не плутайтесь і, будь ласка, не вигадуйте речі, які не існують з причини.

-

PS : Фабрика продуктів - AbstractFactory, а «Фабрика абстрактних фабрик» - це ще один приклад абстрактної фабрики.


як я можу відрізнити AbstractFactory, який створює інші AbstractFactories, від AbstractFactory, який створює конкретні об'єкти? GenericAb Абстракція? Або AbstractFactoryFactory?
Андрій

У моделях дизайну такого немає. Обидва вони є примірниками шаблону AbstractFactory. Отже, один AbstractFactory створює конкретні об'єкти, а інший AbstractFactory створює фабрики (які знову є AbstractFactory).
Тенгіз

Звичайно. То як я називаю ці класи, які роблять різні речі? Тому що створення інших фабрик та створення інших (простих) об’єктів - це дві різні речі. Мене не хвилюють шаблони, мені потрібен читабельний код.
Андрій

3
Читаний код - це код розкриття наміру. При іменуванні класів ви не повинні згадувати занадто багато шаблонів, якщо це не дуже необхідно. Наприклад, якщо у вас є абстрактна фабрика, яка створює різні транспортні засоби, можливо, назвіть це TransportCreator або TransportFactory, а може навіть і TransportManufacturer. І тоді, якщо у вас є фабрика цих фабрик, ви можете назвати її як би там не було - хто відкриє нових виробників. Можливо, це може бути ManufacturerManagement? в основному, називайте речі так, як їх називає ваш бізнес, а НЕ на основі того, які шаблони вони реалізують.
Тенгіз

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це абстрактна фабрика , як він надає методи для створення сімейства родинних продуктів.

Зауважте, що кожен метод на заводі «Анотація» сам по собі є Фабричним методом . Подібний createDough()сам по собі є заводським методом, конкретні реалізації якого забезпечуватимуться підкласами типу NYPizzaIngredientsFactory. Таким чином, використовуючи це, кожне інше місце може створити екземпляри конкретних інгредієнтів, які належать до їх розташування.

Фабричний метод

Надає екземпляр конкретної реалізації

У прикладі:
- createDough()- забезпечує конкретну реалізацію тіста. Тож це заводський метод

Анотація заводу

Забезпечує інтерфейс для створення сімейства пов'язаних об'єктів

У прикладі:
- PizzaIngredientsFactoryце абстрактна фабрика , оскільки це дозволяє створити пов'язаний набір об'єктів , таких як Dough, Clams, Sauce. Для створення кожної родини об'єктів передбачений заводський метод.

Приклад із шаблонів дизайну Head First


5

У мене є деякі моменти, щоб зробити свій внесок у відповідь Джона наступним чином:

Абстрактна фабрика - це фабрика фабрик!

З «Factory Method» (тому що тільки «Фабрика» неоднозначно), ви робите реалізації ( Lemon, Orangeі т.д.) конкретного інтерфейсу - скажімо, IFruit. Цю Фабрику можна було б назвати CitricFruitFactory.

Але тепер ви хочете створити ще один вид фруктів, які CitricFruitFactory не в змозі створити. Можливо, код CitricFruitFactoryне має сенсу, якщо ви створюєте Strawberryв ньому (полуниця - це не лимонний фрукт!).

Таким чином , ви можете створити новий завод під назвою , RedFruitFactoryяка виробляє Strawberry, Raspberryі т.д.

Як сказав Джон Фемінелла: "За допомогою абстрактного фабричного шаблону ви створюєте реалізацію певного фабричного інтерфейсу - наприклад, IFruitFactoryкожен з них знає, як створювати різні види фруктів".

Що впровадження IFruitFactoryє CitricFruitFactoryі RedFruitFactory!


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

Основна різниця цих заводів полягає в тому, що ви хочете робити з фабриками і коли ви хочете їх використовувати.

Іноді, коли ви робите МОК (інверсія управління, наприклад, впорскування конструктора), ви знаєте, що ви можете створювати тверді предмети. Як було сказано в прикладі вище фруктів, якщо ви готові створювати предмети з фруктів, ви можете використовувати просту заводську схему .

Але багато разів не хочеться створювати тверді об’єкти, вони з’являться пізніше в програмному потоці. Але конфігурація говорить вам про те, яку фабрику ви хочете використовувати на старті, замість створення об'єктів ви можете передати фабрики, що походять із загального фабричного класу, до конструктора в МОК.

Отже, я думаю, що це стосується і терміну експлуатації об'єкта, і його створення.


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спеціальний салат з ваших фруктів, і там виходить ваша абстрактна фабрика . Абстрактна фабрика знає, як створити свій спеціальний салат із яблук, бананів та вишні.

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

За визначенням ми можемо перетягнути два відмінності:

Фабрика: Інтерфейс використовується для створення об'єкта, але підклас визначає, який клас інстанціювати. Створення об’єкта робиться тоді, коли це потрібно.

Абстрактна фабрика: абстрактний заводський зразок діє як суперфабрика, яка створює інші заводи. У шаблоні абстрактних заводів інтерфейс відповідає за створення набору пов’язаних об'єктів або залежних об'єктів без конкретизації їх конкретних класів.

Отже, у наведених вище визначеннях ми можемо наголосити на певній різниці. тобто заводський зразок відповідає за створення об'єктів, а абстрактний завод відповідає за створення набору суміжних об'єктів; очевидно, як через інтерфейс.

Заводський зразок:

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();
        }
    }

1

Перевірте тут: http://www.allapplabs.com/java_design_patterns/ab абстракт_factory_pattern.htm Здається, що метод Factory використовує певний клас (не абстрактний) як базовий клас, тоді як абстрактна фабрика використовує для цього абстрактний клас. Також якщо використовувати інтерфейс замість абстрактного класу, результатом буде інша реалізація шаблону абстрактних заводів.

: D


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;
    }

}

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

Другий спосіб (використовуючи заводський зразок): надає вам перевагу, що ви можете пройти будь-який тип реалізації, який може забезпечити різний тип чогось на основі певної умови (можливо, параметр, переданий методу Creative).

Третій спосіб (використовуючи абстрактний заводський візерунок): це дає більше гнучкості. Ви можете знайти різні типи творців чогось на основі певної умови (можливо, пройшов параметр).

Зауважте, що ви завжди можете піти з фабричного шаблону, комбінуючи дві умови разом (що дещо збільшує складність коду та з'єднання), я думаю, тому ми рідко бачимо випадки використання реального життя з абстрактним фабричним малюнком.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.