design patterns - डिजाइन पैटर्न: फैक्टरी विधि बनाम सार फैक्टरी




design-patterns language-agnostic (7)

अगर मैंने एक सारणी (एक इंटरफेस या अमूर्त बेस क्लास के माध्यम से संदर्भित) फैक्टरी क्लास बनाया है जो ऑब्जेक्ट्स बनाता है जिसमें वस्तुओं को बनाने के लिए केवल एक ही विधि है, तो यह एक फैक्टरी विधि होगी

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

मान लें कि मैं एक प्रबंधक बनाता हूं जो एक एमवीसी नियंत्रक के लिए क्रिया विधियों की आवश्यकताओं को संभालेगा। यदि इसकी एक विधि थी, तो इंजन ऑब्जेक्ट्स बनाने के लिए कहें जिनका उपयोग दृश्य मॉडल बनाने के लिए किया जाएगा, फिर यह एक फैक्ट्री विधि पैटर्न होगा। दूसरी ओर यदि इसमें दो विधियां थीं: एक दृश्य मॉडल इंजन बनाने के लिए, और दूसरा एक्शन मॉडल इंजन बनाने के लिए (या जो भी आप मॉडल को कॉल करना चाहते हैं जिसमें एक्शन विधि उपभोक्ता हैं), तो यह एक अमूर्त कारखाना होगा।

public ActionResult DoSomething(SpecificActionModel model)
{
    var actionModelEngine = manager.GetActionModelEngine<SpecificActionModel>();
    actionModelEngine.Execute(SpecificActionModelEnum.Value);

    var viewModelEngine = manager.GetViewModelEngine<SpecificViewModel>();
    return View(viewModelEngine.GetViewModel(SpecificViewModelEnum.Value);
}

नोट: पोस्ट के अंत में प्रश्न हैं।

मैंने सार फैक्ट्री बनाम फैक्टरी विधि के संबंध में अन्य स्टैक ओवरफ्लो धागे पढ़े हैं। मैं प्रत्येक पैटर्न के इरादे को समझता हूं। हालांकि, मैं परिभाषा पर स्पष्ट नहीं हूं।

फैक्टरी विधि ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस को परिभाषित करती है, लेकिन उप-वर्गों को यह तय करने देता है कि उनमें से कौन सा तत्काल है। एक फैक्ट्री विधि कक्षाओं को उप-वर्गों में तत्कालता को स्थगित करने देती है।

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

- जॉन फेमिनेला

सार फैक्टरी फैक्टरी विधि के समान दिखती है। मैंने अपने बिंदु को चित्रित करने के लिए कुछ यूएमएल वर्ग तैयार किए हैं।

ध्यान दें:

  • आरेख www.yuml.com से हैं इसलिए वे पूरी तरह से उन्मुख नहीं हैं। लेकिन यह एक मुफ्त सेवा :)।
  • चित्र सही नहीं हो सकते हैं। मैं अभी भी गोफ डिजाइन पैटर्न सीख रहा हूँ।

फैक्टरी विधि:

सार फैक्टरी (केवल 1 सदस्य):

सार फैक्टरी (अधिक सदस्य):

प्रशन:

  1. यदि सार फैक्ट्री में केवल एक निर्माता और एक उत्पाद है, तो क्या यह अभी भी सार फैक्टरी पैटर्न है? (परिवार बनाने के लिए एक इंटरफ़ेस)
  2. क्या फ़ैक्टरी विधि कंक्रीट निर्माता को इंटरफ़ेस से बनाया जा सकता है या क्या इसे कक्षा से होना चाहिए? (कक्षाएं subclasses को तत्काल स्थगित)
  3. यदि सार फैक्ट्री में केवल एक निर्माता और एक उत्पाद हो सकता है, तो सार फैक्ट्री और फैक्ट्री विधि के बीच एकमात्र अंतर है कि पूर्व के लिए निर्माता इंटरफ़ेस है और उत्तरार्द्ध के लिए निर्माता कक्षा है?

उम्मीद है की यह मदद करेगा। यह विभिन्न प्रकार की कारखानों का वर्णन करता है। मैंने अपने संदर्भ के रूप में हेड फर्स्ट डिज़ाइन पैटर्न का उपयोग किया। मैंने आरेख में yuml.me का उपयोग किया।

स्टेटिक फैक्टरी

उत्पाद के विभिन्न उप प्रकार के उत्पाद के लिए एक स्टेटिक विधि वाला एक वर्ग है।

सरल फैक्टरी

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

फैक्टरी विधि

इसके प्रकार से संबंधित एक प्रकार के उत्पाद का उत्पादन करने के लिए एक विधि शामिल है। (यह एक साधारण फैक्ट्री से बेहतर है क्योंकि प्रकार को उप-वर्ग में स्थगित कर दिया गया है।)

सार फैक्टरी

संबंधित प्रकार के परिवार का उत्पादन करता है। यह फैक्ट्री विधि से काफी अलग है क्योंकि इसमें इसके प्रकारों की एक से अधिक विधि हैं। (यह बेहतर वास्तविक जीवन उदाहरण के लिए अगले आरेख का जटिल है)।

.NET Framework से उदाहरण

DbFactoriesProvider एक साधारण फैक्टरी है क्योंकि इसमें कोई उप-प्रकार नहीं है। DbFactoryProvider एक सार कारखाना है क्योंकि यह कनेक्शन और कमांड ऑब्जेक्ट्स जैसे विभिन्न संबंधित डेटाबेस ऑब्जेक्ट्स बना सकता है।


जहां तक ​​मैं अर्थ फैक्ट्री और फैक्टरी विधि परिभाषाओं को समझता हूं, पहला व्यक्ति स्थिर संदर्भ में लागू होता है और इनपुट पैरामीटर के आधार पर वस्तु प्रदान करता है।

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

तो यह आम तौर पर दोनों पैटर्नों का एक साथ उपयोग करने की ओर जाता है जहां पहले चरण में आप कुछ सामान्य वस्तु बनाते हैं जो संबंधित वस्तुओं के परिवार का वर्णन करता है। इसे स्थैतिक विधि getInstance ("मेरा परिवार का नाम") विधि कहा जाता है। इस तरह की getInstance विधि का कार्यान्वयन यह तय करता है कि कौन सा पारिवारिक वस्तु बनाई जाएगी।

फिर मैं नव निर्मित परिवार वस्तु पर createProduct () विधि को कॉल करता हूं और पारिवारिक वस्तु के आधार पर नया उत्पाद वापस कर दिया जाएगा।

ऐसा लगता है कि ये पैटर्न प्रत्येक के लिए सहयोग करते हैं।

दूसरे शब्दों में सार फैक्टरी "व्हाट" पर ध्यान केंद्रित किया जाएगा और फैक्टरी विधि "कैसे" बनाई जाएगी।


दो पैटर्न निश्चित रूप से संबंधित हैं!

पैटर्न के बीच अंतर आम तौर पर इरादे में होता है।

फैक्टरी विधि का उद्देश्य "ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस परिभाषित करना है, लेकिन उप-वर्गों को यह तय करना है कि कौन सी कक्षा को तत्काल करना है। फैक्टरी विधि वर्ग को उप-वर्गों को तत्काल स्थगित करने देता है।"

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

इन इरादों के बयान (गोफ से उद्धृत) पर पूरी तरह से आधारित, मैं कहूंगा कि वास्तव में फैक्टरी विधि किसी के परिवार के साथ एक "degenerate" सार फैक्टरी है

वे आमतौर पर कार्यान्वयन में भिन्न होते हैं, क्योंकि फैक्टरी विधि सार फैक्ट्री से सरल है।

हालांकि वे कार्यान्वयन में भी संबंधित हैं। जैसा कि गोफ बुक में उल्लेख किया गया है,

सार कारखाना केवल उत्पाद बनाने के लिए एक इंटरफ़ेस घोषित करता है। वास्तव में उन्हें बनाने के लिए यह कंक्रीट उत्पाद उपखंडों पर निर्भर है। ऐसा करने का सबसे आम तरीका प्रत्येक उत्पाद के लिए फैक्ट्री विधि को परिभाषित करना है।

इस सी 2 विकी में इस विषय पर कुछ रोचक चर्चा भी है।


मेरी राय में, दो पैटर्न के बीच मामूली अंतर प्रयोज्यता में रहता है, और इसलिए, जैसा कि पहले से ही कहा गया है, इरादे में

आइए परिभाषाओं को रिक्त करें (दोनों विकिपीडिया से)।

सार फैक्टरी

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

फैक्टरी विधि

ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस को परिभाषित करें, लेकिन इंटरफ़ेस को लागू करने वाले वर्गों को यह तय करने दें कि कौन सी कक्षा को तुरंत चालू करना है । कारखाने की विधि कक्षाओं को उप-वर्गों को स्थगित करने की अनुमति देती है।

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

सार फैक्ट्री एक उप-वर्ग में कई अलग-अलग प्रकार के उदाहरण बनाने और अपने विभिन्न उप-वर्गों में रचनाओं के व्यवहार को विशिष्ट बनाने की अनुमति देती है; आम तौर पर, फैक्टरी विधि केवल एक प्रकार की वस्तु के निर्माण की घोषणा करती है जिसे उप-वर्गीकरण तंत्र के अनुसार विशिष्ट किया जा सकता है। यह अंतर है।

संक्षेप में। आइए मान लें कि उत्पाद बनाने वाली वस्तुओं के सुपर-क्लास को परिभाषित करता है, और उत्पाद ए और उत्पाद बी दो अलग-अलग उप-वर्ग हैं। इसलिए, सार फैक्ट्री विधि में दो विधियां होंगी, createProductA () और createProductB () जिसे विशिष्ट विशिष्ट वर्गों में (सृजन चरणों के संदर्भ में) विशेषीकृत किया जाएगा: फैक्ट्री उप-वर्ग दो परिभाषित कक्षाओं के लिए निर्माण चरणों को विशेषीकृत करते हैं सृजन के तहत वस्तुओं का।

उपर्युक्त उदाहरण के मुताबिक, फैक्ट्री विधि को विभिन्न कारखानों (फैक्ट्री प्रति एक विधि) में उत्पाद ए और उत्पाद बी के निर्माण को सारणीबद्ध करने के लिए अलग-अलग कार्यान्वित किया जाएगा, और सृजन चरणों के आगे विशेषज्ञता को पदानुक्रम में दिया जाएगा जैसा कि यह बनाया गया है ।


हालांकि, यह कई सालों से हुआ है क्योंकि स्टैक ओवरव्लो के लोगों ने इस मुद्दे के बारे में अन्य पदों (पुराने साल 200 9 में) के बारे में सवाल उठाया था, फिर भी मुझे वह जवाब नहीं मिला जो मैं चाहता था।

तो मैंने वेब के माध्यम से शोध करने के कुछ घंटे किए, उदाहरणों की समीक्षा की, और इस निष्कर्ष पर पहुंचे, फैक्टरी विधि से सार फैक्ट्री के प्रमुख अंतर हैं

  • इरादा: सुसंगतता या "दिखने और महसूस" : सार फैक्ट्री का इरादा एक ही शैली के साथ वस्तुओं के परिवार को समूहित करना है (उदा। एक ही दिखने वाला और यूआई विजेट, एक ही स्टाइल कार पार्ट्स, एक ही ओएस से ऑब्जेक्ट्स, इत्यादि) सार फैक्ट्री के कई उदाहरण मुख्य वाक्यांश "वही दिखने और अनुभव" के बारे में बताते हैं।
  • ऑब्जेक्ट्स एक बड़ा समूह ऑब्जेक्ट बनाते हैं : सार फैक्ट्री एक बड़ी वस्तु ऑब्जेक्ट बनाने वाली ऑब्जेक्ट्स का एक परिवार बनाती है, न कि एक ऑब्जेक्ट।
  • बाद में एक नई शैली जोड़ें : यदि हम फैक्टरी विधि का उपयोग करते रहे हैं और मौजूदा बुनियादी ढांचे में शैली का एक नया सेट जोड़ने का प्रयास करते हैं, तो यह दर्दनाक होगा। सार फैक्टरी के साथ, हमें केवल इतना करना है कि एक नया ठोस कारखाना बनाएं जो अमूर्त फैक्ट्री वर्ग लागू करता है।

काउंटर उदाहरण होंगे

  • एक सेडान में इस्तेमाल की जाने वाली स्पोर्ट्स कार के लिए एक कार हिस्सा। यह असंगतता दुर्घटनाओं का कारण बन सकती है।
  • विभिन्न ओएस जीयूआई विजेट्स में एक विंडोज-स्टाइल बटन। यह कुछ भी तोड़ने वाला नहीं है बल्कि मेरे जैसे कुछ लोगों के लिए उपयोगकर्ता अनुभव को नुकसान पहुंचाएगा।
  • बाद में, हम पाते हैं कि सॉफ़्टवेयर को पिछड़े संगत रखने के दौरान हमारे सॉफ़्टवेयर को अगले ओएस अपग्रेड में चलाने की आवश्यकता है, जिसके लिए संगत सिस्टम ऑब्जेक्ट्स के विभिन्न सेट की आवश्यकता होती है।

इसलिए, जब किसी अंतिम ऑब्जेक्ट समूह में ऑब्जेक्ट के अपवाद के बिना एक ही शैली होनी चाहिए और आप इसे "एक ही शैली को रखने" विवरण को छिपाना चाहते हैं, तो हमें सार फैक्ट्री का उपयोग करना चाहिए।


/*
//Factory methods:

//1. Factory Method - Abstract Creator Class



#include <iostream>
#include <string.h>
using namespace std;

const std::string nineNintyCC = std::string("990CC");
const std::string thousandTwoHundredCC = std::string("1200CC");
const std::string ThousandFiveHundredCC = std::string("1500CC");
const std::string fiveThousandCC = std::string("5000CC");

// Product
class Engine
{
    public:
    virtual void packEngine() = 0;  
};

// Concrete products
// concrete product class one
class C990CCEngine: public Engine
{

    public:
    void packEngine()
    {
       cout << "Pack 990CC engine" << endl;   
    }
};

// concrete class Two
class C1200CCEngine: public Engine
{   public:
    void packEngine()
    {
        cout << "pack 1200CC engine" << endl;
    }

};

// Concrete class Three
class C1500CCEngine: public Engine
{
    public:
    void packEngine()
    {
        cout << "Pack 1500CC engine" << endl;
    }

};


// Car Factory:
class CarFactory{
    public:

    virtual Engine* createEngine(const std::string& type) = 0;
};
class Factory: public CarFactory
{
    public:
     Engine *createEngine(const std::string& type)
     {

          if(0 == nineNintyCC.compare(type))
          {    
             return new C990CCEngine;
          }
          else if(0 == thousandTwoHundredCC.compare(type))
          {
             return new C1200CCEngine;
          }
          else if(0 == ThousandFiveHundredCC.compare(type))
          {
             return new C1500CCEngine;
          } 
          else
           {
                 cout << "Invalid factory input" << endl;
             return NULL;
           }
           return NULL;
     }
};

int main()
{

    CarFactory* ptr = new Factory;
    Engine*pEngine =  ptr->createEngine(nineNintyCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(ThousandFiveHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(thousandTwoHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine = ptr-> createEngine(fiveThousandCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    return 0;
}

*/
/*
//
// interface product
#include <iostream>
#include <string>
using namespace std;

class Engine
{
 public:
 virtual void EngineType() = 0;

};

// concrte product
class AltoEngine: public Engine
{
  public:
  void EngineType()
  {
      cout << "Alto Engine" << endl;
  }
};

//Concrte product
class SwiftEngine : public Engine
{
    public:
    void EngineType()
    {
        cout << "Swift Engine" << endl;    
    }
};

class Body
{
   public:
    virtual void bodyType() = 0;

};

class AltoBody: public Body
{
  public:  
    virtual void bodyType()
    {
        cout << "Alto Car Body" << endl;
    }
};

class SwiftBody : public Body
{
    public:
    void bodyType()
    {
        cout << "SwiftCar Body" << endl;
    }

};


class CarFactory
{
   public:
   virtual Engine* createEngineProduct() = 0;
   virtual Body*   createBodyPoduct() = 0;
};
class AltoCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new AltoEngine;
    }
    Body* createBodyPoduct()
    {
        return new AltoBody;
    }

};

class SwiftCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new SwiftEngine;
    }
    Body* createBodyPoduct()
    {
        return new SwiftBody;
    }

};

int main()
{

    CarFactory* pAltoFactory = new AltoCarFactory;
    Engine* pAltoEngine = pAltoFactory->createEngineProduct();
    pAltoEngine->EngineType();
    Body* pAltoBody = pAltoFactory->createBodyPoduct();
    pAltoBody->bodyType();



    CarFactory* pSwiftFactory = NULL;
    pSwiftFactory = new SwiftCarFactory;
    Engine* pSwiftEngine = pSwiftFactory->createEngineProduct();
    pSwiftEngine->EngineType();
    Body* pSwfitBody = pSwiftFactory->createBodyPoduct();
    pSwfitBody->bodyType();
    delete pAltoBody;
    delete pAltoFactory;
    delete pSwfitBody;
    delete pSwiftFactory;
    return 0;
}
*/

/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");
// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Engine Engine" << endl;
  }

};
// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Engine" << endl;
    }

};
// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Engine" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createFactory(const std::string&) = 0;
};

// EngineFactory
class CarEngineFactory : public CarFactory
{
     public:
     CarEngine* createFactory(const std::string&  type)
     {
          if(0 == maruthi.compare(type))
          {
              return new MaruthiEngine;

          }
          else if(0 == fiat.compare(type))
          {
              return  new FiatEngine;
          }
          else if(0 == renault.compare(type))
          {
              return new RenaultEngine;
          }
          else
          {
              cout << "Invalid Engine type" << endl;
              return NULL;
          }
     }

  };

int main()
{
    CarFactory* pCarFactory = new CarEngineFactory;
    CarEngine* pMaruthiCarEngine = pCarFactory->createFactory(maruthi);
    pMaruthiCarEngine->engineType();

    CarEngine* pFiatCarEngine = pCarFactory->createFactory(fiat);
    pFiatCarEngine->engineType();


    CarEngine* pRenaultCarEngine = pCarFactory->createFactory(renault);
    pRenaultCarEngine->engineType();

    return 0;
}


*/


/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");


// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Car Engine" << endl;
  }

};

// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Car Engine" << endl;
    }

};

// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Car Engine" << endl;
    }
};

// Interface
class CarBody
{
 public:
    virtual void bodyType() = 0;
};

// Concrete class
class FiatBody: public CarBody
{
  public:
  void bodyType()
  {
      cout << "Fait car Body" << endl;
  }

};

// ConcreteClass
class RenaultBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Renault Body" << endl;
    }

};

// Concrete class
class MaruthiBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Maruthi body" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createCarEngineProduct() = 0;
    virtual CarBody* createCarBodyProduct() = 0;
};

// FiatFactory
class FaitCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
        return new FiatEngine; 
     }
     CarBody* createCarBodyProduct()
     {
         return new FiatBody;
     }
};

// Maruthi Factory
class MaruthiCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
         return new MaruthiEngine;
     }
     CarBody* createCarBodyProduct()
     {
         return new MaruthiBody;
     }

};

// Renault Factory
class RenaultCarFactory : public CarFactory
{
     public:
    CarEngine* createCarEngineProduct()
    {
        return new RenaultEngine;
    }

    CarBody* createCarBodyProduct()
    {
        return new RenaultBody;
    }

};


int main()
{

   // Fiat Factory
   CarFactory* pFiatCarFactory = new FaitCarFactory;
   CarEngine* pFiatEngine = pFiatCarFactory->createCarEngineProduct();
   CarBody*  pFiatBody = pFiatCarFactory->createCarBodyProduct();
   pFiatEngine->engineType();
   pFiatBody->bodyType();

   // Renault Car Factory
    return 0;
}

*/




abstract-factory