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

Վիքիպեդիայից՝ ազատ հանրագիտարանից
Ֆաբրիկային մեթոդ
Անգլերեն անվանում` Factory method
Տեսակ` Ստեղծող
Նշանակություն` Մեկ ինտերֆեյսով տարբեր տիպի օբյեկտներ ստեղծելու համար։
Կառուցվածք` FactoryMethod.svg
Առավելություններ` Օբյեկտների ստեղծում անկախ օբյեկտների տիպից և ստեղծման պրոցեսի բարդությունից
Թերություններ` Նույնիսկ մեկ օբյեկտի համար անհրաժեշտ է ստեղծել համապատասխան ֆաբրիկա, որը բերում է կոդի մեծացման։
Նկարագրությունը ԳօՖի
"Design Patterns" գրքում`
Այո

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

Ընդհանուր հասկացողություններ[խմբագրել | խմբագրել կոդը]

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

Նկարագրություն[խմբագրել | խմբագրել կոդը]

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

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

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

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

Կառուցվածք[խմբագրել | խմբագրել կոդը]

Ֆաբրիկային մեթոդի կառուցվածքը

Օրինակներ[խմբագրել | խմբագրել կոդը]

C#[խմբագրել | խմբագրել կոդը]

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

//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 դասի հավելումն է։ Այն օբյեկտ է ստեղծում դասի ինտերֆեյսի միջոցով, բայց մյուս կողմից ենթադասերին թույլ է տալիս, որ իրենք որոշեն, թե ինչ դասից պետք է նմուշը վերցվի։

//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 ինտերֆեյսում դառնում է աբստրակտ։

Սահմանափակումներ[խմբագրել | խմբագրել կոդը]

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

  • Առաջինի սահմանափակումը կայանում է նրանում, որ գոյություն ունեցող դասը, ֆաբրիկաների օգտագործման համար վերակազմակերպման ենթարկելիս, կտրում է (անգլ.՝ breaks) հայցողներից (անգլ.՝ clients)։ Օրինակ, եթե Complex դասը ստանդարտ դաս է, ապա այն ունի բազմաթիվ հայցողներ հետևյալ տեսքով.
Complex c = new Complex(-1, 0);

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

  • Երկրորդ սահմանափակումը կայանում է նրանում, որ դասը հնարավոր չէ ընդարձակել, քանի որ նախագծման մոդելը հիմնված է փակ (անգլ.՝ private) կոնստրուկտոր օգտագործելու վրա։ Ամեն մի ենթադաս պետք է կանչի ժառանգ կոնստրուկտորին, բայց դա հնարավոր չէ իրականացնել, քանի որ կոնստրուկտորը փակ է։
  • Երրորդ սահմանափակումը նրանումն է, որ եթե դասը ընդարձակվել է (օրինակ եթե կոնստրուկտորը պաշտպանված է հայտարարած), ենթադասը պետք է բոլոր ֆաբրիկաների համար տա իր սեփական վերաիրականացումը (անգլ.՝ re-implementation)։ Օրինակ, եթե StrangeComplex դասը Complex դասի ընդարփակումն է, ապա StrangeComplex դասը պետք է բոլոր ֆաբրիկաների համար ունենա իր սեփական տարբերակը։
StrangeComplex.fromPolar(1, pi);

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

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

Կիրառություններ[խմբագրել | խմբագրել կոդը]

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

Ծանոթագրություններ[խմբագրել | խմբագրել կոդը]

  1. "Factory Pattern", OODesign.com
  2. Chapter 4. The Factory Pattern: Baking with OO Goodness: The Simple Factory defined
  3. Design Patterns from the Gang Of Four
  4. 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-09-12 
  5. Agerbo Ellen, Cornils Aino (1998)։ «How to preserve the benefits of design patterns»։ Conference on Object Oriented Programming Systems Languages and Applications (Vancouver, British Columbia, Canada: ACM): 134–143։ ISBN 1-58113-005-8