Абстра́ктна фа́брика (англ. Abstract Factory) — шаблон проєктування, що забезпечує інкапсуляцію окремих фабрик під єдиною схемою, упускаючи їхню деталізацію. Належить до класу твірних шаблонів.
В типових випадках застосування, клієнтський код створює конкретну реалізацію абстрактної фабрики, а потім використовує загальний універсальний інтерфейс фабрики, для створення екземплярів об'єктів, які є частиною схеми. Клієнтський код не знає (або не бере до уваги), які саме конкретно об'єкти він отримує від цих фабрик, оскільки він використовує універсальний інтерфейс для їхнього створення. Шаблон розмежовує деталі реалізації множини об'єктів від їхнього загального використання в коді, оскільки створення об'єкта здійснюється за допомогою методів, що забезпечуються інтерфейсом фабрики.
Призначення
Подає інтерфейс для утворення родин взаємозв'язаних або взаємозалежних об'єктів, не специфікуючи їхніх конкретних класів.
Застосування
Слід використовувати шаблон Абстрактна фабрика коли:
- система не повинна залежати від того, як утворюються, компонуються та представляються вхідні до неї об'єкти;
- вхідні до родини взаємозв'язані об'єкти повинні використовуватися разом і необхідно забезпечити виконання цього обмеження;
- система повинна конфігуруватися однією з родин складаючих її об'єктів;
- треба подати бібліотеку об'єктів, розкриваючи тільки їхні інтерфейси, але не реалізацію.
Структура
- AbstractFactory — абстрактна фабрика:
- оголошує інтерфейс для операцій, що створюють абстрактні об'єкти-продукти;
- ConcreteFactory — конкретна фабрика:
- реалізує операції, що створюють конкретні об'єкти-продукти;
- AbstractProduct — абстрактний продукт:
- оголошує інтерфейс для типу об'єкта-продукту;
- ConcreteProduct — конкретний продукт:
- визначає об'єкт-продукт, що створюється відповідною конкретною фабрикою;
- реалізує інтерфейс AbstractProduct;
- Client — клієнт:
- користується виключно інтерфейсами, котрі оголошенні у класах AbstractFactory та AbstractProduct.
Переваги
- ізолює конкретні класи;
- спрощує заміну сімейств продуктів;
- гарантує сполучуваність продуктів.
Недоліки
- Важко добавити підтримку нового виду продуктів
Відносини
- Зазвичай під час виконання створюється єдиний екземпляр класу ConcreteFactory. Ця конкретна фабрика створює об'єкти продукти, що мають досить визначену реалізацію. Для створення інших видів об'єктів клієнт повинен користуватися іншою конкретною фабрикою;
- AbstractFactory передоручає створення об'єктів продуктів своєму підкласу ConcreteFactory.
Реалізація
C++
#include <string> #include <iostream> using namespace std; // Сімейство елементів // Базовий клас для всіх іграшок class Toy { protected: string name; public: Toy(string name) { this->name = name; } }; // Конкретні реалізації struct WoodenCat : public Toy { WoodenCat() : Toy("Wooden Cat") { cout << this->name << '\n'; } }; struct TeddyCat : public Toy { TeddyCat() : Toy("Teddy Cat") { cout << this->name << '\n'; } }; struct WoodenBear : public Toy { WoodenBear() : Toy("Wooden Bear") { cout << this->name << '\n'; } }; struct TeddyBear : public Toy { TeddyBear() : Toy("Teddy Bear") { cout << this->name << '\n'; } }; // Абстрактна Фабрика (Abstract Factory) struct IToyFactory { virtual Toy * GetBear() = 0; virtual Toy * GetCat() = 0; }; // конкретна фабрика (concrete factory) struct TeddyToysFactory : IToyFactory { virtual Toy * GetBear() { return new TeddyBear(); } virtual Toy * GetCat() { return new TeddyCat(); } }; // і ще одна конкретна фабрика struct WoodenToysFactory : IToyFactory { virtual Toy * GetBear() { return new WoodenBear(); } virtual Toy * GetCat() { return new WoodenCat(); } }; // Client void create(IToyFactory * toyFactory) { Toy * bear = toyFactory->GetBear(); Toy * cat = toyFactory->GetCat(); } void main() { // Спочатку створимо «дерев'яну» фабрику auto p1 = WoodenToysFactory(); auto p2 = TeddyToysFactory(); create(&p1); // А тепер створимо «плюшеву» фабрику, create(&p2); }
Swift
Протокол
protocol Decimal { func stringValue() -> String // factory static func make(string : String) -> Decimal } typealias NumberFactory = (String) -> Decimal // Number implementations with factory methods struct NextStepNumber : Decimal { private var nextStepNumber : NSNumber func stringValue() -> String { return nextStepNumber.stringValue } // factory static func make(string : String) -> Decimal { return NextStepNumber(nextStepNumber:NSNumber(longLong:(string as NSString).longLongValue)) } } struct SwiftNumber : Decimal { private var swiftInt : Int func stringValue() -> String { return "\(swiftInt)" } // factory static func make(string : String) -> Decimal { return SwiftNumber(swiftInt:(string as NSString).integerValue) } }
Абстрактна фабрика
enum NumberType { case NextStep, Swift } class NumberHelper { class func factoryFor(type : NumberType) -> NumberFactory { switch type { case .NextStep: return NextStepNumber.make case .Swift: return SwiftNumber.make } } }
Використання
let factoryOne = NumberHelper.factoryFor(.NextStep) let numberOne = factoryOne("1") numberOne.stringValue() let factoryTwo = NumberHelper.factoryFor(.Swift) let numberTwo = factoryTwo("2") numberTwo.stringValue()
PHP
<?php // Загальний Інтерфейс реалізації interface GuiFactoryInterface { public function buildButton(): ButtonInterface; public function buildCheckBox(): CheckBoxInterface; } interface ButtonInterface { public function draw(); } interface CheckBoxInterface { public function draw(); } // Кінцева реалізація class ButtonBootstrap implements ButtonInterface { public function draw() {return __CLASS__;} } class CheckBoxBootstrap implements CheckBoxInterface { public function draw() {return __CLASS__;} } class ButtonSemanticUI implements ButtonInterface { public function draw() {return __CLASS__;} } class CheckBoxSemanticUI implements CheckBoxInterface { public function draw() {return __CLASS__;} } // Інтерфейси для зв'язку однопитності class BootstrapFactory implements GuiFactoryInterface { public function buildButton(): ButtonInterface { return new ButtonBootstrap(); } public function buildCheckBox(): CheckBoxInterface { return new CheckBoxBootstrap(); } } class SemanticUIFactory implements GuiFactoryInterface { public function buildButton(): ButtonInterface { return new ButtonSemanticUI(); } public function buildCheckBox(): CheckBoxInterface { return new CheckBoxSemanticUI(); } } class GuiKitFactory { public function getFactory($type): GuiFactoryInterface { switch ($type) { case 'bootstrap': $factory = new BootstrapFactory(); break; case 'semantic_ui': $factory = new SemanticUIFactory(); break; default: throw new Exception('Невідомий тип фабрики [' . $type . ']'); } return $factory; } } class CreationPatternController { private $guiKit; public function __construct() { $this->guiKit = (new GuiKitFactory())->getFactory('bootstrap'); // OR //$this->guiKit = (new GuiKitFactory())->getFactory('semantic_ui'); } function AbstractFactory() { $result[] = $this->guiKit->buildCheckbox()->draw(); $result[] = $this->guiKit->buildButton()->draw(); return $result; } } $drawer = new CreationPatternController(); $drawer->AbstractFactory();
Примітки
- Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (ред.). . 1. O'REILLY: 162. ISBN . Архів оригіналу (paperback) за 30 квітня 2020. Процитовано 12 вересня 2012.
Джерела
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 листопада 2012 у Wayback Machine.]
- Design Patterns implemented in Swift 2 [ 30 січня 2016 у Wayback Machine.]
- Дизайн-патерни — просто, як двері [ 10 жовтня 2020 у Wayback Machine.]
Примітки
- Будай, Андрій (2012). Дизайн-патерни — просто, як двері (Українською) . с. 90.
Література
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Abstra ktna fa brika angl Abstract Factory shablon proyektuvannya sho zabezpechuye inkapsulyaciyu okremih fabrik pid yedinoyu shemoyu upuskayuchi yihnyu detalizaciyu Nalezhit do klasu tvirnih shabloniv V tipovih vipadkah zastosuvannya kliyentskij kod stvoryuye konkretnu realizaciyu abstraktnoyi fabriki a potim vikoristovuye zagalnij universalnij interfejs fabriki dlya stvorennya ekzemplyariv ob yektiv yaki ye chastinoyu shemi Kliyentskij kod ne znaye abo ne bere do uvagi yaki same konkretno ob yekti vin otrimuye vid cih fabrik oskilki vin vikoristovuye universalnij interfejs dlya yihnogo stvorennya Shablon rozmezhovuye detali realizaciyi mnozhini ob yektiv vid yihnogo zagalnogo vikoristannya v kodi oskilki stvorennya ob yekta zdijsnyuyetsya za dopomogoyu metodiv sho zabezpechuyutsya interfejsom fabriki PriznachennyaPodaye interfejs dlya utvorennya rodin vzayemozv yazanih abo vzayemozalezhnih ob yektiv ne specifikuyuchi yihnih konkretnih klasiv ZastosuvannyaSlid vikoristovuvati shablon Abstraktna fabrika koli sistema ne povinna zalezhati vid togo yak utvoryuyutsya komponuyutsya ta predstavlyayutsya vhidni do neyi ob yekti vhidni do rodini vzayemozv yazani ob yekti povinni vikoristovuvatisya razom i neobhidno zabezpechiti vikonannya cogo obmezhennya sistema povinna konfiguruvatisya odniyeyu z rodin skladayuchih yiyi ob yektiv treba podati biblioteku ob yektiv rozkrivayuchi tilki yihni interfejsi ale ne realizaciyu StrukturaUML diagrama sho opisuye strukturu shablonu proyektuvannya Abstraktna fabrika AbstractFactory abstraktna fabrika ogoloshuye interfejs dlya operacij sho stvoryuyut abstraktni ob yekti produkti ConcreteFactory konkretna fabrika realizuye operaciyi sho stvoryuyut konkretni ob yekti produkti AbstractProduct abstraktnij produkt ogoloshuye interfejs dlya tipu ob yekta produktu ConcreteProduct konkretnij produkt viznachaye ob yekt produkt sho stvoryuyetsya vidpovidnoyu konkretnoyu fabrikoyu realizuye interfejs AbstractProduct Client kliyent koristuyetsya viklyuchno interfejsami kotri ogoloshenni u klasah AbstractFactory ta AbstractProduct Perevagiizolyuye konkretni klasi sproshuye zaminu simejstv produktiv garantuye spoluchuvanist produktiv NedolikiVazhko dobaviti pidtrimku novogo vidu produktivVidnosiniZazvichaj pid chas vikonannya stvoryuyetsya yedinij ekzemplyar klasu ConcreteFactory Cya konkretna fabrika stvoryuye ob yekti produkti sho mayut dosit viznachenu realizaciyu Dlya stvorennya inshih vidiv ob yektiv kliyent povinen koristuvatisya inshoyu konkretnoyu fabrikoyu AbstractFactory peredoruchaye stvorennya ob yektiv produktiv svoyemu pidklasu ConcreteFactory RealizaciyaC Priklad realizaciyi movoyu S include lt string gt include lt iostream gt using namespace std Simejstvo elementiv Bazovij klas dlya vsih igrashok class Toy protected string name public Toy string name this gt name name Konkretni realizaciyi struct WoodenCat public Toy WoodenCat Toy Wooden Cat cout lt lt this gt name lt lt n struct TeddyCat public Toy TeddyCat Toy Teddy Cat cout lt lt this gt name lt lt n struct WoodenBear public Toy WoodenBear Toy Wooden Bear cout lt lt this gt name lt lt n struct TeddyBear public Toy TeddyBear Toy Teddy Bear cout lt lt this gt name lt lt n Abstraktna Fabrika Abstract Factory struct IToyFactory virtual Toy GetBear 0 virtual Toy GetCat 0 konkretna fabrika concrete factory struct TeddyToysFactory IToyFactory virtual Toy GetBear return new TeddyBear virtual Toy GetCat return new TeddyCat i she odna konkretna fabrika struct WoodenToysFactory IToyFactory virtual Toy GetBear return new WoodenBear virtual Toy GetCat return new WoodenCat Client void create IToyFactory toyFactory Toy bear toyFactory gt GetBear Toy cat toyFactory gt GetCat void main Spochatku stvorimo derev yanu fabriku auto p1 WoodenToysFactory auto p2 TeddyToysFactory create amp p1 A teper stvorimo plyushevu fabriku create amp p2 Swift Priklad realizaciyi na movi Swift Protokol protocol Decimal func stringValue gt String factory static func make string String gt Decimal typealias NumberFactory String gt Decimal Number implementations with factory methods struct NextStepNumber Decimal private var nextStepNumber NSNumber func stringValue gt String return nextStepNumber stringValue factory static func make string String gt Decimal return NextStepNumber nextStepNumber NSNumber longLong string as NSString longLongValue struct SwiftNumber Decimal private var swiftInt Int func stringValue gt String return swiftInt factory static func make string String gt Decimal return SwiftNumber swiftInt string as NSString integerValue Abstraktna fabrika enum NumberType case NextStep Swift class NumberHelper class func factoryFor type NumberType gt NumberFactory switch type case NextStep return NextStepNumber make case Swift return SwiftNumber make Vikoristannya let factoryOne NumberHelper factoryFor NextStep let numberOne factoryOne 1 numberOne stringValue let factoryTwo NumberHelper factoryFor Swift let numberTwo factoryTwo 2 numberTwo stringValue PHP Priklad realizaciyi na movi PHP lt php Zagalnij Interfejs realizaciyi interface GuiFactoryInterface public function buildButton ButtonInterface public function buildCheckBox CheckBoxInterface interface ButtonInterface public function draw interface CheckBoxInterface public function draw Kinceva realizaciya class ButtonBootstrap implements ButtonInterface public function draw return CLASS class CheckBoxBootstrap implements CheckBoxInterface public function draw return CLASS class ButtonSemanticUI implements ButtonInterface public function draw return CLASS class CheckBoxSemanticUI implements CheckBoxInterface public function draw return CLASS Interfejsi dlya zv yazku odnopitnosti class BootstrapFactory implements GuiFactoryInterface public function buildButton ButtonInterface return new ButtonBootstrap public function buildCheckBox CheckBoxInterface return new CheckBoxBootstrap class SemanticUIFactory implements GuiFactoryInterface public function buildButton ButtonInterface return new ButtonSemanticUI public function buildCheckBox CheckBoxInterface return new CheckBoxSemanticUI class GuiKitFactory public function getFactory type GuiFactoryInterface switch type case bootstrap factory new BootstrapFactory break case semantic ui factory new SemanticUIFactory break default throw new Exception Nevidomij tip fabriki type return factory class CreationPatternController private guiKit public function construct this gt guiKit new GuiKitFactory gt getFactory bootstrap OR this gt guiKit new GuiKitFactory gt getFactory semantic ui function AbstractFactory result this gt guiKit gt buildCheckbox gt draw result this gt guiKit gt buildButton gt draw return result drawer new CreationPatternController drawer gt AbstractFactory PrimitkiFreeman Eric Freeman Elisabeth Kathy Sierra Bert Bates 2004 Hendrickson Mike Loukides Mike red 1 O REILLY 162 ISBN 978 0 596 00712 6 Arhiv originalu paperback za 30 kvitnya 2020 Procitovano 12 veresnya 2012 DzherelaDesign Patterns Elements of Reusable Object Oriented Software 9 listopada 2012 u Wayback Machine Design Patterns implemented in Swift 2 30 sichnya 2016 u Wayback Machine Dizajn paterni prosto yak dveri 10 zhovtnya 2020 u Wayback Machine PrimitkiBudaj Andrij 2012 Dizajn paterni prosto yak dveri Ukrayinskoyu s 90 LiteraturaAlan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5