Ֆաբրիկային մեթոդ (նախագծման ձևանմուշ)

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

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

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

Այս մեթոդի էությունը ստեղծվող օբյեկտի ինտերֆեյսը որոշելու մեջ է՝ թույլ տալով ինտերֆեյսն իրականցվող դասերին ինքնուրույն որոշել, թե ինչ ենթադասերի միջոցով օբյեկտը պետք է ստեղծվի։ Ֆաբրիկային մեթոդը դասերի օրինակների ստեղծումը թողնում է ենթադասերի վրա։

Օբյեկտների ստեղծումը հաճախ պահանջում է բարդ պրոցեսներ, որտեղ նպատակահարմար չէ ընդգրկել ստեղծված օբյեկտը ()։ Օբյեկտների ստեղծումը կարող է բերել կոդի զգալի կրկնությունների, հնարավոր է անհրաժեշտ լինի ինֆորմացիա, որն հասանելի չէ ստեղծվող օբյեկտին, հնարավոր է չապահովի անհրաժեշտ մակարդակի աբստրակցիա։ Ֆաբրիկային մեթոդն այս խնդիրները լուծում է օբյեկտների ստեղծման առանձին մեթոդ կիրառելով, որի համաձայն ենթադասն է որոշում այն արգասիքի () ենթատեսակը, որը պետք է ստեղծվի։

Ֆաբրիկային մեթոդը հիմնվում է ժառանգման վրա, քանի որ օբյեկտի ստեղծումը տեղափովում է ենթադասերի վրա, որոնք իրականացնում է ֆաբրիկային մեթոդը օբյեկտներ ստեղծելու համար։

## Կառուցվածք
500px|center|Ֆաբրիկային մեթոդի կառուցվածքը

## Օրինակներ
### C#
Ֆաբրիկային մեթոդը գործ ունի օբյեկտի նմուշի հետ առանց հետաքրքվելու նմուշի ստեղծման տրամաբանության մեջ։ Այլ խոսքերով ասած Ֆաբրիկան փաստացի համարվում է ընդհանուր ինտերֆեյս ունեցող օբյեկտի ստեղծողը։


```csharp
//IVSR:Factory Pattern
//Empty vocabulary of Actual object
public interface IPeople
{
    string GetName();
}

public class Villagers : IPeople
{
    #region IPeople Members

    public string GetName()
    {
        return "Village Guy";
    }

    #endregion
}

public class CityPeople : IPeople
{
    #region IPeople Members

    public string GetName()
    {
        return "City Guy";
    }

    #endregion
}

public enum PeopleType
{
    RURAL,
    URBAN
}

/// <summary>
/// Implementation of Factory - Used to create objects
/// </summary>
public class Factory
{
    public IPeople GetPeople(PeopleType type)
    {
        IPeople people = null;
        switch (type)
        {
            case PeopleType.RURAL :
                people = new Villagers();
                break;
            case PeopleType.URBAN:
                people = new CityPeople();
                break;
            default:
                break;
        }
        return people;
    }
}
```


Վերը բերված կոդում կարող եք տեսնել IPeople անվանմամբ մի ինտերֆեյսի ստեղծման օրինակ և նրա միջոցով Villagers և CityPeople երկու դասերի իրականացում։ Կախված թե ինչ տիպ ենք փոխանցել ֆաբրիկային օբյեկտին, մենք հետ կստանանք կոնկրետ տիպի օբյեկտ որպես IPeople ինտերֆեյս։

Ֆաբրիկային մեթոդը դա պարզապես Factory դասի հավելումն է։ Այն օբյեկտ է ստեղծում դասի ինտերֆեյսի միջոցով, բայց մյուս կողմից ենթադասերին թույլ է տալիս, որ իրենք որոշեն, թե ինչ դասից պետք է նմուշը վերցվի։


```csharp
//IVSR:Factory Pattern

public interface IProduct
{
    string GetName();
    string SetPrice(double price);
}

public class IPhone : IProduct 
{
    private double _price;
    #region IProduct Members

    public string GetName()
    {
        return "Apple TouchPad";
    }

    public string SetPrice(double price)
    {
        this._price = price;
        return "success";
    }

    #endregion
}

/* Almost same as Factory, just an additional exposure to do something with the created method */
public abstract class ProductAbstractFactory
{
       
    protected abstract IProduct DoSomething();

    public IProduct GetObject() // Implementation of Factory Method.
    {
        return this.DoSomething();
    }
}

public class IPhoneConcreteFactory : ProductAbstractFactory
{

    protected override IProduct DoSomething()
    {
        IProduct product = new IPhone();
        //Do something with the object after you get the object. 
        product.SetPrice(20.30);
        return product;
    }
}
```


Դուք կարող եք տեսնե, որլ GetObject-ը օգտագործվում է ConcreteFactory-ում։ Արդյունքում նրանից հեշտությամբ կարելի է կանչել DoSomething () ֆունկցիան, որպեսզի IProduct-ը ստանանք։ Դուք նույնպես կարող եք ձեր լոգիկան գրել կոնկրետ Factory Method-ից ձեր օբյեկտը ստանալու համար։ GetObject-ը Factory ինտերֆեյսում դառնում է աբստրակտ։

## Սահմանափակումներ
Ֆաբրիկային մեթոդի օգտագործման հետ գոյություն ունի երեք սահմանափակում։ Առաջինը վերաբերվում է կոդի վերակազմակերպմանը (), իսկ մյուս երկուսը կոդի ընդարձակմանը։

* Առաջինի սահմանափակում նրանում է, որ գոյություն ունեցող դասը, ֆաբրիկաների օգտագործման համար վերակազմակերպման ենթարկելիս, կտրում է () հայցողներից ()։ Օրինակ, եթե Complex դասը ստանդարտ դաս է, ապա այն ունի բազմաթիվ հայցողներ հետևյալ տեսքով.


```java
Complex c = new Complex(-1, 0);
```


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

* Երկրորդ սահմանափակումը նրանում է, որ դասը հնարավոր չէ ընդարձակել, քանի որ նախագծման մոդելը հիմնված է փակ () կոնստրուկտոր օգտագործելու վրա։ Ամեն մի ենթադաս պետք է կանչի ժառանգ կոնստրուկտորին, բայց դա հնարավոր չէ իրականացնել, քանի որ կոնստրուկտորը փակ է։
* Երրորդ սահմանափակումը նրանումն է, որ եթե դասը ընդարձակվել է (օրինակ եթե կոնստրուկտորը պաշտպանված է հայտարարած), ենթադասը պետք է բոլոր ֆաբրիկաների համար տա իր սեփական վերաիրականացումը ()։ Օրինակ, եթե `StrangeComplex` դասը `Complex` դասի ընդարփակումն է, ապա `StrangeComplex` դասը պետք է բոլոր ֆաբրիկաների համար ունենա իր սեփական տարբերակը։


```java
StrangeComplex.fromPolar(1, pi);
```
 կոդի կանչը կտա `Complex` (սուպերդաս) նմուշ, բայց ոչ թե սպասված ենթադասի նմուշ։ Որոշ ծրագրավորման լեզուներ, իրենց յուրահատկություններից ելնելով, կարող են խուսափել այս խնդրից։

Բոլոր երեք խնդիրները կարելի է լուծել ծրարգրավորման լեզվի փոփոխմամբ, որտեղ հնարավոր կլինի առաջին-դասի ֆաբրիկաները դարձնել դասի անդամներ ()։

## Կիրառություններ
* ADO.NET, IDbCommand.CreateParameter; Ֆաբրիկան կիրառվում է զուգահեռ դասի հիերարխիային միանալու համար։
* Qt, QMainWindow::createPopupMenu  Ֆաբրիկայի մեթոդը կիրառվում է framework-ում, որտեղ ենթադրվում է, որ ծրագրի կոդը կարող է փոխարինվի այլ կոդով։
* Java, մի քանի ֆաբրիկաներ են օգտագործվում javax.xml.parsers փաթեթում։ Օրինակ javax.xml.փարսերներ .DocumentBuilderFactory կամ javax.xml.փարսերներ.SAXParserFactory.

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

Կատեգորիա:Ծրագրավորում