हमें एब्सट्रैक्ट फ़ैक्टरी डिज़ाइन पैटर्न की आवश्यकता क्यों है?


124

अधिकांश परिभाषा कहती है:

एक अमूर्त कारखाना अपने ठोस वर्गों को निर्दिष्ट किए बिना संबंधित वस्तुओं के परिवारों को बनाने के लिए एक इंटरफ़ेस प्रदान करता है

एब्सट्रैक्ट फ़ैक्टरी पैटर्न का क्या उपयोग होता है क्योंकि हम ठोस वर्ग की वस्तु बनाकर कार्य को प्राप्त कर सकते हैं। हमारे पास एक फैक्ट्री पद्धति क्यों है जो कंक्रीट क्लास की वस्तु बनाती है?

कृपया मुझे कोई वास्तविक जीवन उदाहरण प्रदान करें जहां मुझे अमूर्त पैटर्न को लागू करना चाहिए?

जवाबों:


219

एसेंश फैक्ट्री डिपेंडेंसी इंजेक्शन (DI) के लिए एक बहुत ही केंद्रीय डिजाइन पैटर्न है । यहां स्टैक ओवरफ्लो प्रश्नों की एक सूची दी गई है जहां सार फैक्ट्री के आवेदन को समाधान के रूप में स्वीकार किया गया है।

मेरी समझ के अनुसार, ये प्रश्न वास्तविक चिंताओं या समस्याओं का प्रतिनिधित्व करते हैं जो लोगों के पास थीं, इसलिए आपको कुछ वास्तविक जीवन के उदाहरणों के साथ शुरू करना चाहिए:


6
ये सभी उदाहरण फ़ैक्टरी विधि पैटर्न का वर्णन करते हैं, क्योंकि उनमें से सभी एक एकल उत्पाद इंटरफ़ेस लौटाते हैं। इनमें से कोई भी एब्सट्रैक्ट फैक्ट्री पैटर्न नहीं है, क्योंकि उनमें से कोई भी संबंधित उत्पाद इंटरफेस के एक परिवार का उत्पादन नहीं करता है।
jaco0646

32
पूर्ण प्रकटीकरण के हित में, इस उत्तर के लेखक को यह स्पष्ट करना चाहिए कि वह जुड़े हुए उत्तरों में से हर एक का लेखक भी है; इसलिए यह सूची एसओ समुदाय का प्रतिनिधि नमूना नहीं है।
jaco0646

1
@ jaco0646 IIRC, फैक्टरी विधि पैटर्न के एक विशेषज्ञता है टेम्पलेट विधि पैटर्न , जो विरासत पर निर्भर करता है। हालाँकि, मुझसे गलती हो रही है, क्योंकि मैं इस समय यात्रा कर रहा हूँ, और मेरे साथ मेरी GoF पुस्तक नहीं है। आपका क्या मतलब है "उनमें से कोई भी संबंधित उत्पाद इंटरफेस के एक परिवार का उत्पादन नहीं करता है"?
मार्क सेमन जूल

1
सबसे सरल सुराग जो किसी फैक्ट्री को इंगित करता है, एब्सट्रैक्ट फैक्ट्री पैटर्न के अनुरूप नहीं है, फैक्ट्री द्वारा निर्मित अमूर्त उत्पादों को गिनने के लिए है (मैंने "अमूर्त उत्पादों" के स्थान पर "अमूर्त उत्पादों" के स्थान पर "अमूर्त" शब्द के प्रयोग से बचने के लिए शब्द का प्रयोग किया है) । एक फैक्ट्री जो एक सार उत्पाद का उत्पादन करती है, वह एब्सट्रैक्ट फैक्ट्री नहीं हो सकती है, क्योंकि परिभाषा के अनुसार एब्सट्रैक्ट फैक्ट्री संबंधित उत्पादों का एक परिवार तैयार करती है । यह ध्यान रखना महत्वपूर्ण है कि यह परिवार एक इंटरफ़ेस के विभिन्न कार्यान्वयनों का उल्लेख नहीं कर रहा है, बल्कि विभिन्न, संबंधित इंटरफेस वाले उत्पादों के लिए है।
jaco0646

1
यहाँ एक उदाहरण है oodesign.com/abstract-factory-pattern.html । यह वही है जो अमूर्त कारखाने पैटर्न के लिए मूल रूप से बनाया गया था।
user2802557

23

एब्सट्रैक्ट फ़ैक्टरी पैटर्न के उपयोग के लिए एक वास्तविक जीवन उदाहरण दो अलग-अलग डेटा स्रोतों के लिए डेटा एक्सेस प्रदान कर रहा है। मान लें कि आपका एप्लिकेशन विभिन्न डेटा स्टोर का समर्थन करता है। (जैसे एक SQL डेटाबेस और एक XML फ़ाइल)। आपके पास उपयोग किए गए डेटा स्रोत के प्रकार की परवाह किए बिना आपके एप्लिकेशन द्वारा अपेक्षित सामान्य विधियों को परिभाषित करने IReadableStoreऔर IWritableStoreपरिभाषित करने के लिए दो अलग-अलग डेटा एक्सेस इंटरफेस हैं ।

किस प्रकार के डेटा स्रोत का उपयोग किया जाना चाहिए, ग्राहक कोड को डेटा एक्सेस कक्षाओं के पुनर्प्राप्त करने के तरीके में बदलाव नहीं करना चाहिए। आपका AbstractDataAccessFactoryपता है कि किस प्रकार का डेटा स्रोत कॉन्फ़िगर किया गया है और क्लाइंट कोड के लिए एक ठोस फैक्टरी प्रदान करता है , SqlDataAccessFactoryया XmlDataAccessFactory। ये ठोस कारखाने ठोस कार्यान्वयन को बना सकते हैं, जैसे SqlReadableStoreऔर SqlWriteableStore

DbProviderFactory .NET फ्रेमवर्क में इस पद्धति का एक उदाहरण है।


18
यह उत्तर फ़ैक्टरी विधि पैटर्न, या स्टेटिक फ़ैक्टरी पैटर्न का सही-सही वर्णन कर सकता है, लेकिन एब्सट्रैक्ट फ़ैक्टरी पैटर्न नहीं।
jaco0646

5

अगर मैं आपको सही समझता हूं - सवाल यह है कि हमारे पास फैक्टरी विधि और अमूर्त कारखाना पैटर्न दोनों क्यों हैं। जब अलग-अलग पॉलिमॉर्फिक वर्गों में अलग-अलग तात्कालिकता प्रक्रिया होती है, तो आपको अमूर्त कारखाने की आवश्यकता होती है। और आप चाहते हैं कि कुछ मॉड्यूल इंस्टेंसेस बनाएं और उनका उपयोग करें, बिना ऑब्जेक्ट इनिशियलाइज़ेशन के किसी भी विवरण को जाने। उदाहरण के लिए - आप कुछ गणना करने वाले जावा ऑब्जेक्ट बनाना चाहते हैं। लेकिन उनमें से कुछ आवेदन का हिस्सा हैं, जबकि अन्य के बायोटेक को डीबी से पढ़ा जाना चाहिए। दूसरे हाथ में - हमें फैक्टरी विधि की आवश्यकता क्यों है? सहमत हूँ, कि अमूर्त कारखाना इसे ओवरलैप करता है। लेकिन कुछ मामलों में - यह लिखने के लिए बहुत कम कोड है, कम कक्षाएं और इंटरफेस होने से सिस्टम को समझने में आसानी होती है।


4

एब्सट्रैक्ट फ़ैक्टरी पैटर्न का क्या उपयोग होता है क्योंकि हम ठोस वर्ग की वस्तु बनाकर कार्य को प्राप्त कर सकते हैं। हमारे पास एक फैक्ट्री पद्धति क्यों है जो कंक्रीट क्लास की वस्तु बनाती है?

एब्सट्रैक्ट फैक्ट्री की अनुपस्थिति में , क्लाइंट को कंक्रीट कक्षाओं का विवरण जानना होगा। इस टाइट कपलिंग को एब्सट्रैक्ट फैक्ट्री से हटा दिया गया है ।

अब फैक्ट्री मेथड एक कॉन्ट्रैक्ट को उजागर करता है, जिसे क्लाइंट को इस्तेमाल करना होता है। आप नए उत्पादों को जोड़कर अपने कारखाने में अधिक उत्पाद जोड़ सकते हैं, जो फैक्टरी विधि द्वारा उजागर किए गए इंटरफ़ेस को लागू करते हैं।

बेहतर समझ के लिए इन संबंधित एसई प्रश्नों का संदर्भ लें:

फ़ैक्टरी और एब्सट्रैक्ट फ़ैक्टरी पैटर्न के बीच बुनियादी अंतर क्या है?

आशय:

अपने ठोस वर्गों को निर्दिष्ट किए बिना संबंधित या आश्रित वस्तुओं के परिवारों को बनाने के लिए एक इंटरफ़ेस प्रदान करें।

आप इस स्रोत लेख से सार फैक्टरी पैटर्न के अंगूठे के इरादे, संरचना, चेकलिस्ट और नियमों को समझ सकते हैं ।

चेकलिस्ट:

  1. यह तय करें कि क्या प्लेटफॉर्म की स्वतंत्रता और निर्माण सेवाएं दर्द का मौजूदा स्रोत हैं।
  2. प्लेटफ़ॉर्म बनाम उत्पादों के मैट्रिक्स को मैप करें ।
  3. फ़ैक्टरी इंटरफ़ेस को परिभाषित करें जिसमें प्रति उत्पाद फैक्टरी विधि शामिल है।
  4. प्रत्येक प्लेटफ़ॉर्म के लिए फ़ैक्टरी व्युत्पन्न वर्ग को परिभाषित करें जो नए ऑपरेटर को सभी संदर्भों को एन्क्रिप्ट करता है।
  5. ग्राहक नए सभी संदर्भों को समाप्त कर दी, और का उपयोग करना चाहिए कारखाने तरीकों बनाने के लिए उत्पाद वस्तुओं।

2

आपके कोड-बेस को एकीकृत रखते हुए कई प्लेटफार्मों का समर्थन करने के लिए सार फैक्ट्रियां महान हैं। मान लें कि आपके पास एक बड़ा Qt या GTK + या .NET / मोनो प्रोग्राम है जिसे आप विंडोज, लिनक्स और OSX पर चलाना चाहते हैं। लेकिन आपके पास एक विशेषता है जो प्रत्येक प्लेटफ़ॉर्म पर अलग तरीके से लागू की जाती है (शायद कर्नेल 32 एपीआई या पॉसिक्स सुविधा के माध्यम से)।

public abstract class Feature
{
    public abstract int PlatformSpecificValue { get; }

    public static Feature PlatformFeature
    {
        get
        {
            string platform;
            // do platform detection here
            if (platform == "Win32")
                return new Win32Feature();
            if (platform == "POSIX")
                return new POSIXFeature();
        }
    }

    // platform overrides omitted
}

इस सार फैक्ट्री के साथ, आपके UI को वर्तमान प्लेटफ़ॉर्म के बारे में कुछ भी जानने की आवश्यकता नहीं है।

Feature feature = Feature.PlatformFeature;
Console.WriteLine(feature.PlatformSpecificValue);

1
मुझे यह नहीं मिलता है, यह कैसे एक अमूर्त प्रकार को वापस करने के लिए कारखाने के तरीकों का उपयोग करने से अलग है ताकि ग्राहक कार्यान्वयन विवरणों को नहीं जान सके?
कीवीकोमबेज़

1

यदि आप डिजाइन पैटर्न को देखते हैं, तो उनमें से लगभग सभी को बेमानी बनाया जा सकता है। लेकिन क्या पैटर्न का मतलब एक समान प्रकार की समस्याओं के समाधान के लिए आमतौर पर इस्तेमाल किया जाने वाला दृष्टिकोण है। एक डिज़ाइन पैटर्न आपको समान प्रकार की डिज़ाइन समस्या के सेट के लिए डिज़ाइन स्तर का दृष्टिकोण या समाधान प्रदान करता है। डिजाइन पैटर्न का उपयोग करने से आपको अपनी समस्या को हल करने में मदद मिलती है और इसलिए तेजी से वितरण होता है।


1

यह आसान है, इमेजिंग कि आपके पास एक कोड है जो अमूर्त के साथ काम करता है, आपको अमूर्त बनाना चाहिए न कि ठोस कक्षाएं।

आपको हमेशा सार के खिलाफ काम करना चाहिए क्योंकि आप कोड को बेहतर तरीके से संशोधित कर सकते हैं।

यह एक अच्छा उदाहरण है: http://en.wikipedia.org/wiki/Abstract_factory_pattern#C.2.23


1

मुझे ओवररेट फैक्ट्री पैटर्न ओवररेटेड लगता है।

सबसे पहले, ऐसा नहीं होता है कि अक्सर आपके पास परस्पर संबंधित प्रकार का एक सेट होता है जिसे आप तुरंत भेजना चाहते हैं।

दूसरे, निर्भरता इंजेक्शन के साथ काम करते समय इंटरफेस द्वारा प्रदान की जाने वाली अप्रत्यक्षता (अमूर्तता) का स्तर सामान्य रूप से पर्याप्त होता है।

WindowsGui बनाम MacGui बनाम का विशिष्ट उदाहरण ... जहाँ आपके पास WindowsButton, MacButton, WindowsScrollBar, MacScrollbar, आदि होते हैं, जहां विज़िटर और / या दुभाषिया पैटर्न का उपयोग करके कंक्रीट बटन, स्क्रॉलबार इत्यादि को परिभाषित करके लागू करना आसान होता है । वास्तविक व्यवहार।


इसके लिए एक विशिष्ट उद्देश्य है। निर्भरता इंजेक्शन के साथ आप नहीं चाहते कि सर्विस लोकेटर आगे कम्पोजिट रूट से नीचे जाए। इसके बजाय आप एक इंजेक्टेड एब्सट्रैक्ट फैक्ट्री का उपयोग करें।
एडम टिलिपर - MSFT

2
अच्छी तरह से ... DI के साथ सेवा लोकेटर का उपयोग करना एक विरोधी पैटरन है। जब हम रनटाइम मान से DEPENDENCIES बनाने की आवश्यकता होती है, तो एक सार कारखाना एक सार्वभौमिक समाधान होता है।
मेंटर

1

मुझे लगता है कि ऐसे स्थानों में जहां वे तात्कालिकताएं बहुत जटिल हैं, एक ही कारखाने के लिए बहुत जटिल और बदसूरत हैं और यूआई के लिए भी जटिल हैं, अमूर्त कारखाना पैटर्न के लिए एक जगह है।

मान लीजिए कि यह एक एकल वर्ग नहीं एक TYPE_A ब्रांड है .. मान लीजिए कि टाइप-ए के समान वर्गों के 100 प्रकार का एक परिवार है और आपको उनसे एक वस्तु को तुरंत प्राप्त करने की आवश्यकता है। कल्पना करें कि कई समान प्रकार की वस्तुओं के एक ब्रांड से बाहर सही वस्तु बनाने के लिए एक विस्तृत परिष्कृत जानकारी की आवश्यकता होती है, और इस वस्तु इकाई में आपको यह जानने की आवश्यकता है कि वास्तव में कौन से मापदंडों को ट्यून करना है और उन्हें कैसे ट्यून करना है।

इस ब्रांड के लिए विशेष कारखाने में हम उन्हें अलग-अलग करेंगे और उन्हें तत्काल वस्तु और सटीक वस्तु प्राप्त कर सकते हैं। हमें पता चलेगा कि नेट से इनपुट के अनुसार (मान लीजिए कि ऑनलाइन स्टोर में कौन सा रंग उपलब्ध है), और पृष्ठभूमि में चल रहे अन्य एप्लिकेशन और सेवाओं से (पैरामीटर यूआई उनके बारे में पता नहीं है)।

और हो सकता है कि कल हमारे पास एक और परिवार हो, जो कहे कि टाइप_ और टाइप_ सी को तुरंत बताएं। यूआई में "यदि और" है, तो यह जानने के लिए कि क्या उपयोगकर्ता को "type_A", "type_B" या "type_C" चाहिए - लेकिन फैक्ट्रीज़ कक्षाएं तय करेगी कि किस वर्ग से (परिवार से) टाइप करें, और इसे कैसे ट्यून किया जाए - इसके मापदंडों को क्या मान दिया जाए, या इसके ठेकेदार को भेजा जाए। यह सब - कई मापदंडों के अनुसार जो यूआई के बारे में पता नहीं है। यह सब एक कारखाने के वर्ग के लिए बहुत अधिक होगा।


1

वास्तविक जीवन का उदाहरण System.Data.Common नामस्थान में दिया गया है जिसमें सार आधार कक्षाएं हैं जिसमें DbConnection, DbCommand, और DbDataAdapter शामिल हैं और .NET फ्रेमवर्क डेटा प्रदाताओं द्वारा साझा किए जाते हैं, जैसे System .ata.SqlClient और System.Data.OracleClient एक जेनरिक डेटा एक्सेस कोड लिखने के लिए डेवलपर को सक्षम करें जो एक विशिष्ट डेटा प्रदाता पर निर्भर नहीं करता है।

DbProviderFactories वर्ग DbProviderFactory उदाहरण बनाने के लिए स्थैतिक तरीके प्रदान करता है। इसके बाद प्रदाता सूचना के आधार पर सही ढंग से टाइप की गई वस्तु और रन टाइम पर दिए गए कनेक्शन स्ट्रिंग को लौटाता है।

उदाहरण:

 DataTable allProvidersTable = DbProviderFactories.GetFactoryClasses();

यहाँ छवि विवरण दर्ज करें

        /* Getting SqlClient family members */
        DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
        DbCommand dbCommand = dbProviderFactory.CreateCommand();
        DbConnection dbConnection = dbProviderFactory.CreateConnection();
        DbDataAdapter dbDataAdapter = dbProviderFactory.CreateDataAdapter();

        SqlClientFactory sqlClientFactory = (SqlClientFactory)dbProviderFactory;
        SqlConnection sqlConnection = (SqlConnection)dbConnection;
        SqlCommand sqlCommand = (SqlCommand) dbCommand;
        SqlDataAdapter sqlDataAdapter = (SqlDataAdapter) dbDataAdapter;

        /* Getting OracleClient family members*/
        dbProviderFactory = DbProviderFactories.GetFactory("System.Data.OracleClient");
        dbCommand = dbProviderFactory.CreateCommand();
        dbConnection = dbProviderFactory.CreateConnection();
        dbDataAdapter = dbProviderFactory.CreateDataAdapter();

        OracleClientFactory oracleClientFactory = (OracleClientFactory)dbProviderFactory;
        OracleConnection oracleConnection = (OracleConnection)dbConnection;
        OracleCommand oracleCommand = (OracleCommand)dbCommand;
        OracleDataAdapter oracleDataAdapter = (OracleDataAdapter)dbDataAdapter;

उदाहरण -2 यहाँ छवि विवरण दर्ज करें

कोड समाधान वास्तुकला यहाँ छवि विवरण दर्ज करें

नीचे के रूप में स्थिर फैक्टरी विधि का उपयोग करके कंक्रीट कारखाने के उदाहरण दिए गए हैं

public  class FurnitureProviderFactory
{
    public static IFurnitureFactory GetFactory(string furnitureType)
    {
        if (furnitureType == "Wood")
        {
            return new WoodenFurnitureFactory();
        }
        if (furnitureType == "Plastic")
        {
            return new PlasticFurnitureFactory();
        }
        throw new Exception("Undefined Furniture");
    }
}

0

सीधे अपने सवाल का जवाब देने के लिए, आप शायद इस तरह के डिजाइन पैटर्न का उपयोग किए बिना दूर हो सकते हैं।

हालाँकि, ध्यान रखें कि वास्तविक दुनिया में अधिकांश परियोजनाएँ विकसित होती हैं और आप अपनी परियोजना को भविष्य में प्रूफ बनाने के लिए किसी प्रकार की व्यापकता प्रदान करना चाहते हैं।

अपने स्वयं के अनुभव से, ज्यादातर समय, एक कारखाने को लागू किया जाता है और जैसे-जैसे यह परियोजना बढ़ती है, यह अधिक जटिल डिजाइन पैटर्न जैसे कि एब्सट्रैक्ट फैक्ट्री में बदल जाती है।


0

यह सब निर्भरता के बारे में है। यदि आप तंग युग्मन और निर्भरता के बारे में परवाह नहीं करते हैं, तो आपको एक सार कारखाने की आवश्यकता नहीं है। लेकिन जैसे ही आप एक आवेदन लिखते हैं जो रखरखाव की आवश्यकता है, यह बात होगी।


0

कहते हैं कि आप a.jar बनाते हैं, और कोई व्यक्ति आपके जार का उपयोग करता है और अपने कोड में एक नई ठोस वस्तु का उपयोग करना चाहता है। यदि आप अमूर्त कारखाने का उपयोग नहीं कर रहे हैं, तो उसे आपके कोड को संशोधित करना होगा या आपके कोड को ओवरराइट करना होगा। लेकिन अगर आप अमूर्त कारखाने का उपयोग कर रहे हैं, तो वह एक कारखाना प्रदान कर सकता है और आपके कोड को पास कर सकता है और सब कुछ ठीक है।

परिष्कृत संस्करण: बेलो परिदृश्य पर विचार करें version किसी और ने एक रूपरेखा लिखी। रन टाइम में बहुत सी वस्तुओं को बनाने के लिए फ्रेमवर्क एक अमूर्त कारखाने और कुछ ठोस कारखानों का उपयोग करता है। तो आप आसानी से मौजूदा ढाँचे में अपना कारखाना पंजीकृत कर सकते हैं और अपनी वस्तुएँ बना सकते हैं। अमूर्त कारखाने पैटर्न के कारण फ्रेमवर्क संशोधनों के लिए बंद है और अभी भी विस्तार करना आसान है।


0

यह पैटर्न विशेष रूप से तब उपयोगी होता है जब ग्राहक को यह पता नहीं होता है कि किस प्रकार का निर्माण करना है। एक उदाहरण के रूप में, मान लें कि सेलफोन विशेष रूप से सेलिंग सेल को सैमसंग द्वारा बनाए गए स्मार्ट फोन के लिए एक क्वेरी मिलती है। यहाँ हमें सटीक प्रकार की वस्तु नहीं बनती है (यह मानते हुए कि किसी फ़ोन के लिए सभी जानकारी ठोस वस्तु के रूप में लिपटी हुई है)। लेकिन हम जानते हैं कि हम सैमसंग द्वारा निर्मित स्मार्ट फोन की तलाश कर रहे हैं। यह जानकारी वास्तव में उपयोग की जा सकती है यदि हमारे डिजाइन में एब्सट्रैक्ट फैक्ट्री कार्यान्वयन हो।

C # में एब्सट्रैक्ट फैक्ट्री पैटर्न को समझना और लागू करना

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.