**Աբստրակտ ֆաբրիկա** նախագծման ձևանմուշը իրենից ներկայացնում է առանձին ֆաբրիկաների ինկապսուլյացայի մեթոդ, որտեղ վերոհիշյալ ֆաբրիկաներն ունեն ընդհանուր թեմատիկա՝ առանց իրենց կոնկրետ դասերը մատնանշելու։ Սովորական օգտագործման դեպքում ծրագրային ապահովումը ստեղծում է աբստրակտ ֆաբրիկայի կոնկրետ իրականացում, իսկ այնուհետև ընդհանուր ինտերֆեյս է օգտագործում կոնկրետ օբյեկտների ստեղծման համար, որոնք որ հանդիսանում են թեմայի մաս։ Հայցողը (անգլ.՝ client) չգիտե, թե ինչ կոնկրետ օբյեկտներ է ստանում ամեն մի ներքին ֆաբրիկայից, քանի որ նա իր ապրանքները (անգլ.՝ products) ստեղծելու համար օգտագործում է ընդհանուր ինտերֆեյս։ Մոդելն առանձնացնում է իրականացման մանրամասները օբյեկտների բազմությունից և հիմնվում է օբյեկտի կոմպոզիցիայի վրա, որտեղ օբյեկտի ստեղծումը իրականացվում է ֆաբրիկայի ինտերֆեյսի մեթոդներով։

Որպես Աբստրակտ ֆաբրիկայի նմւոշ կարող է հանդիսանալ `DocumentCreator` դասը, որն ինտերֆեյսներ է ապահովում մի շարք արգասիքներ (անգլ.՝ product) (օրինակ `createLetter()` և `createResume()`) ստեղծելու համար։ Այս համակարգը կունենա ցանակացած քանակության `DocumentCreator` դասերի տարբերակներ, որպիսիք են `FancyDocumentCreator` կամ `ModernDocumentCreator`, որոնցից ամեն մեկն ունի `createLetter()` և `createResume()` իրականացումներ, որպեսզի ստեղծի համապատասխանաբար `FancyLetter` կամ `ModernResume` օբյեկտներ։ Այս արգասիքներից յուրաքանչյուրն հանդիսանում է պարզ աբստրակտ `Letter` կամ `Resume` դասերի տեսքով, որոնց ճանաչում է հայցողը (անգլ.՝ client)։ Հայցողի կոդը կստանա `DocumentCreator`-ի համապատասխան օրինակ և կկանչի իր ֆաբրիկային մեթոդը։ Բոլոր ստացված օբյեկտները կիրականացվեն միևնույն `DocumentCreator`-ի միջոցով։ Հայցողը միայն պետք է իմանա, թե ինչպես պետք է դիմել `Letter` կամ `Resume` աբստրակտ դասերին, այլ ոչ թե ֆաբրիկային մեթոդի հատուկ տարբերակի կանչը։

**Ֆաբրիկան** հանդիսանում է կոնկրետ դաս ծրագրավորման կոդի մեջ, որի միջոցով ստեղծվում է օբյեկտները։ Այս նախագծման ձևանմուշի օգտագործման նպատակահարմարությունը նրանումն է, որ առանձնացնվի օբյեկտի ստեղծումը նրա օգտագործումից կամ էլ կապակցված օբյեկտների ընտանիքի ստեղծումը, որոնք կախված չեն կոնկրետ դասերից։ Դա թույլ է տալիս նոր կամայական տիպ ներմուծել կոդի մեջ առանց բազային կոդը փոփոխման ենթարկելու։

Այս ձևանմուշի օգտագործումը թույլ է տալիս տեղերով փոփոխել կոնկրետ իրականացումները առանց դրանք կանչվող կոդի փոփոխության, անգամ ծրագրի իրականացման պահին։ Այնուամենայնիվ, այս ձևանմուշի, ինչպես նաև նմանատիպ այլ նախագծման մոդելներների օգտագործումը կարող է դառնալ ավելորդ բարդության և լրացուցիչ աշխատանքի պատճառ սկզբանական կոդը կազմելիս։ Բացի այդ կոդի բարձր մակարդակի բաժանումը և աբստրակցիան կարող են համակարգը դարձնել դժվար սպասարկվող և թեսթավորվող։ Դրա համար էլ նախքան այն կիրառելը բոլոր թեր և դեմ կողմերը պետք է լրջորեն ուսումնասիրել։

Ընդհանուր հասկացողություններ
----------------------------

* Client - հայցող
* Instance - նմուշ
* Implementation - իրականացում
* Product - արգասիք

Նկարագրություն
--------------

Աբստրակտ ֆաբրիկա նախագծման ձևանմուշն ինտերֆեյս է ապահովում կապակցված ընտանիքների կամ փոխկապակցված օբյեկտների ստեղծման համար՝ առանց մատնանշելու նրանց կոնկրետ դասերը

Օգտագործումը
------------

**Ֆաբրիկան** միայն որոշում է թե ինչ **կոնկրետ** տիպի օբյեկտ պետք է ստեղծվի և որտեղից օբյեկտը իրականում պետք է ստեղծվի (օրինակ C++ լեզվում **new** օպերատորի) կիրառմամբ։ Այնուամենայնիվ, ֆաբրիկան միայն **աբստրակտ** ցուցիչ է վերադարձնում ստեղծված կոնկրետ օբյեկտի վրա։

Այս մեխանիզմը մեկուսացնում է հայցողի կոդը օբյեկտի ստեղծումից։ Հայցողը ֆաբրիկայից ցանկալի տիպի օբյեկտ է կանչում և ստանում է աբստրակտ ցուցիչ այդ օբյեկտի վրա։

Քանի որ ֆաբրիկան վերադարձնում է միայն աբստրակտ ցուցիչ, հայցողի կոդը (որ ֆաբրիկայից օբյեկտ է հայցել) չգիտե, թե այդ պահին կոնկրետ ինչ օբյեկտ ստեղծվեց։ Այնուամենայնիվ, կոնկրետ օբյեկտի տիպը (և, հետևաբար, կոնկրետ ֆաբրիկան) հանդիսանում է որպես աբստրակտ ֆաբրիկայի նմուշ (անգլ.՝ instance)։ Ֆաբրիկան այն կարող է կարդալ կոնկրետ կոնֆիգուրացիոն ֆայլից։ Մասնավորապես դա նշանակում է.

* Հայցողի կոդը ընդհանրապես կախված չէ կոնկրետ տիպից և կարիք չկա այնտեղ ներառել որևէ **header file** կամ էլ դաս հայտարարել։ Հայցողի կոդը գործ ունի միայն աբստրակտ տիպի հետ։ Կոնկրետ տիպի օբյեկտները իրականում ստեղծվում են ֆաբրիկայում, բայց հայցողի կոդին օբյեկտները հասանելի է միայն նրանց աբստրակտ ինտերֆեյսի միջոցով։
* Նոր կոնկրետ տիպերի ավելացումն արվում է հայցողի կոդի փոփոխմամբ՝ օգտագործելով այլ ֆաբրիկա։ Տարբեր ֆաբրիկաներ ստեղծում են **տարբեր** տիպերի կոնկրետ օբյեկտներ, բայց նախկինի պես վերադարձնում են նույն տիպի աբստրակտ ցուցիչ՝ մեկուսացնելով հայցողի կոդը փոփոխություններից։ Սա ավելի հեշտ է, քան հայցողի կոդի փոփոխումը, որպեսզի ստեղծվի նոր տիպի օբյեկտ, որը կպահանջեր փոփոխություններ կատարել կոդի **բոլոր** մասերում, որտեղ որ ստեղծվում է նոր օբյեկտը (ինչպես նաև համոզվել, որ կոդի այդ մասերում բավարար ինֆորմացիա կա նոր կոնկրետ տիպի մասին՝ ներառելով դասի **header** ֆայլը)։ Եթե ֆաբրիկայի օբյեկտները պահվում են որպես գլոբալ միայնակ օբյեկտ և հայցողի կոդը մի անգամ է կանչում տվյալ ֆաբրիկային օբյեկտ ստեղծելու համար, ապա ֆաբրիկայի օբյեկտի փոփոխումը նույնքան հեշտ է, որքան որ միայնակ օբյեկտի փոփոխումը։

Կառուցվածք
----------

### Խելացի դասի սխեմա

`GuiFactory` ինտերֆեյսի `createButton` մեթոդը վերադարձնում է `Button` տիպի օբյեկտը։ `Button` օբյեկտի վերադարձի իրականացումը կախված է `GuiFactory`-ի կանչի մեթոդից։

### UML դասի սխեմա

Պսեվդոկոդ
---------

Կախված թե ինչ ֆաբրիկա է օգտագործվում, պետք է պատկերել կոճակը կամ Windows կամ էլ Mac OS X ոճով։ Ուշադրություն դարձրեք, որ ծրագիրը գաղափար անգամ չունի, թե ինչ GUIFactory է կանչվում կոճակը ստեղծելու ժամանակ։

```
**interface** Button **is**
 **method** paint()

**interface** GUIFactory **is**
 **method** createButton()
   **output:**  a *button*

**class** WinFactory implementing GUIFactory **is**
 **method** createButton() **is**
   **output:**  a Windows button
  Return a new WinButton

**class** OSXFactory implementing GUIFactory **is**
 **method** createButton() **is**
   **output:**  an OS X button
  Return a new OSXButton

**class** WinButton implementing Button **is**
 **method** paint() **is**
  Render a button in a Windows style

**class** OSXButton implementing Button **is**
 **method** paint() **is**
  Render a button in a Mac OS X style

**class** Application is
 **constructor** Application(factory) **is**
   **input:**  the GUIFactory *factory* used to create buttons
  Button button := factory.createButton()
  button.paint()

Read the configuration file
**If** the OS specified in the configuration file is Windows, **then**
 **Construct** a WinFactory
 **Construct** an Application with WinFactory
**else**
 **Construct** an OSXFactory
 **Construct** an Application with OSXFactory
```

Օրինակներ
---------

### C#

Աբստրակտ ֆաբրիկան բազային Ֆաբրիկա մոդելի ընդլայնումն է։ Այն ապահովում է Ֆաբրիկա ինտերֆեյսներ փոխկապակցված դասերի ընտանիք ստեղծելու համար։

```
/\*IVSR:Abstract factory pattern\*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AbstractFactory
{
 public class GenericFactory<T> 
 where T : new()
 {
 public T CreateObject()
 {
 return new T();
 }
 }

 public abstract class CarFactory
 {
 public abstract SportsCar CreateSportsCar();
 public abstract FamilyCar CreateFamilyCar();
 }
 
 public abstract class FamilyCar
 {
 public abstract void Speed(SportsCar abstractFamilyCar);
 }

 public abstract class SportsCar
 {
 }

 public class MercedesFactory : CarFactory
 {
 public override SportsCar CreateSportsCar()
 {
 return new MercedesSportsCar();
 }

 public override FamilyCar CreateFamilyCar()
 {
 return new MercedesFamilyCar();
 }
 }
 
 
 class MercedesSportsCar : SportsCar
 {
 }

 class MercedesFamilyCar : FamilyCar
 {
 public override void Speed(SportsCar abstractSportsCar)
 {
 Console.WriteLine(GetType().Name + "is slower than "
 + abstractSportsCar.GetType().Name);
 }
 }

 public class Driver
 {
 private CarFactory \_carFactory;
 private SportsCar \_sportsCar;
 private FamilyCar \_familyCar;

 public Driver(CarFactory carFactory)
 {
 CarFactory = carFactory;
 SportsCar = CarFactory.CreateSportsCar();
 FamilyCar = CarFactory.CreateFamilyCar();
 }

 private CarFactory CarFactory
 {
 get { return \_carFactory; }
 set { \_carFactory = value; }
 }

 private SportsCar SportsCar
 {
 get { return \_sportsCar; }
 set { \_sportsCar = value; }
 }

 private FamilyCar FamilyCar
 {
 get { return \_familyCar; }
 set { \_familyCar = value; }
 }

 public void CompareSpeed()
 {
 FamilyCar.Speed(SportsCar);
 }
 }
}

```

Ֆաբրիկային մեթոդը նույնպես իրականացված է ընդհանուր ինտերֆեյսից օգտվելով, և նրանցից յուրաքանչյուրը վերադարձնում է օբյեկտներ։

```
//IVSR: Abstract factory using common interface
public interface IFactory1
 {
 IPeople GetPeople();
 }
 public class Factory1 : IFactory1
 {
 public IPeople GetPeople()
 {
 return new Villagers();
 }
 }

 public interface IFactory2
 {
 IProduct GetProduct();
 }
 public class Factory2 : IFactory2
 {
 public IProduct GetProduct()
 {
 return new IPhone();
 }
 }

 public abstract class AbstractFactory12
 {
 public abstract IFactory1 GetFactory1();
 public abstract IFactory2 GetFactory2();
 }

 public class ConcreteFactory : AbstractFactory12
 {

 public override IFactory1 GetFactory1()
 {
 return new Factory1();
 }

 public override IFactory2 GetFactory2()
 {
 return new Factory2();
 }
 }

```

Ծանոթագրություններ
------------------

1. ↑  «Паттерн Abstract Factory». Արխիվացված օրիգինալից 2013 թ․ հունիսի 14-ին. Վերցված է 2013 թ․ հունիսի 14-ին.
2. 1 2  Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (eds.). «Head First Design Patterns» (paperback). **1**. O'REILLY: 156. ISBN 978-0-596-00712-6. Վերցված է 2012 թ․ սեպտեմբերի 12-ին. `{{cite journal}}`: Cite journal requires `|journal=` (օգնություն)
3. 1 2  Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (eds.). «Head First Design Patterns» (paperback). **1**. O'REILLY: 162. ISBN 978-0-596-00712-6. Վերցված է 2012 թ․ սեպտեմբերի 12-ին. `{{cite journal}}`: Cite journal requires `|journal=` (օգնություն)
4. ↑  Gamma, Erich; Richard Helm; Ralph Johnson; John M. Vlissides (2009 թ․ հոկտեմբերի 23). «Design Patterns: Abstract Factory». informIT. Արխիվացված է օրիգինալից 2012 թ․ մայիսի 16-ին. Վերցված է 2012 թ․ մայիսի 16-ին. «Object Creational: Abstract Factory: Intent: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.»
5. ↑  Veeneman, David (2009 թ․ հոկտեմբերի 23). «Object Design for the Perplexed». The Code Project. Արխիվացված է օրիգինալից 2011 թ․ փետրվարի 21-ին. Վերցված է 2012 թ․ մայիսի 16-ին. «The factory insulates the client from changes to the product or how it is created, and it can provide this insulation across objects derived from very different abstract interfaces.»
6. 1 2  «Abstract Factory: Implementation». OODesign.com. Վերցված է 2012 թ․ մայիսի 16-ին.

Արտաքին հղումներ
----------------

* Abstract Factory Արխիվացված 2008-04-15 Wayback Machine UML սխեմա + նկարագրություն

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * դ
* ք
* խ
Նախագծման ձևանմուշներ |
| --- |
|  |
| ԳօՖիձևանմուշներ | 

|  |  |
| --- | --- |
| Ստեղծող | Աբստրակտ ֆաբրիկա* Կառուցող
* Ֆաբրիկային մեթոդ
* Նախատիպ
* Եզակի օգտագործման
 |
| Կառուցվածքային | Ադապտեր* Կամուրջ
* Կազմող
* Դեկորատոր
* Ճակատ
* Հարմարեցնող
* Պրոքսի
 |
| Վարքագծային | Պարտականությունների շղթա* Հրաման
* Թարգմանիչ
* Իտերատոր
* Միջնորդ
* Պահպանող
* Դիտորդ
* Վիճակ
* Մարտավարություն
* Կաղապարային մեթոդ
* Այցելող
 |

 |
|  |
| Ստեղծող ձևանմուշներ | 
* Ծույլ բեռնում
* Բազմակի օգտագործման
* Օբյեկտների ավազան
* Ռեսուրսի ստանալը ինիցիալիզացիա է

 |
|  |
| Կառուցվածքային ձևանմուշներ | Ճակատը հսկող
* Մոդուլ
 |
|  |
| Համաձայնեցման ձևանմուշներ | 
* Ակտիվ օբյեկտ
* Հենվող
* Մեկուսացում կրկնակի ստուգումով
* Ասինքրոն կանչի մեթոդ
* Պահպանվող կախոց
* Ռեգիստրացնող
* Կողպեքավորող
* Մոնիտոր
* Նախագործող
* Ապագործող
* Ընթերցողներ-գրողի կողպեք
* Պլանավորման
* Հոսքերի ավազանի
* Հոսքերի լոկալ հիշողություն

 |
|  |
| Ճարտարապետական ձևանմուշներ | 
* Ճակատը հսկող ձևանմուշ
* Զավթող ձևանմուշ
* ձևանմուշի ներկայացման վերահսկում
* Բազմաշերտ
* Հատկորոշում
* Հրատարակող-ստորագրող
* Մերկ օբյեկտներ
* Ծառայության լոկատոր
* Ակտիվ գրառման
* Բազմության իդենտիֆիկացման
* Data access object
* Data transfer object

 |
|  |
| Այլ ձևանմուշներ | 
* Կախվածության ներդնում
* Mock օբյեկտ
* Զրոյական օբյեկտ
* Ծառայող
* Թունելային տարատեսակի

 |

 |