design patterns - सार कारखाना पैटर्न



design-patterns c#-4.0 (1)

सबसे पहले, मैं आपको सार फैक्टरी पैटर्न के बारे में पढ़ने के लिए सुझाव दूंगा, उदाहरण के लिए here । अब मैं यह बताने की कोशिश करूंगा कि आप इस पैटर्न का उपयोग क्यों करेंगे।

आम तौर पर, यदि आप फैक्टरी पैटर्न का उपयोग करते हैं, तो आप फैक्ट्री में ऑब्जेक्ट्स बनायेंगे। समस्या तब उत्पन्न होती है जब आपके पास किसी दिए गए वर्ग (या कक्षाओं) के एकाधिक कार्यान्वयन होते हैं। अब, उन एकाधिक कार्यान्वयन को समूहीकृत किया गया है। जब आपके पास Abstract Factory pattern तो आप Abstract Factory pattern उपयोग करेंगे, लेकिन आप प्रति समूह वस्तुओं के निर्माण को समूहबद्ध करना चाहते हैं।

ठीक है, स्पष्टीकरण के ऊपर पूरी तरह से स्पष्ट नहीं हो सकता है, इसलिए मैं आपको एक उदाहरण दूंगा।

मान लीजिए कि आपके पास डेटा एजेंटों के साथ क्लास लाइब्रेरी है। डेटा एजेंट आपको विभिन्न डेटा तक पहुंचने और स्टोर करने के तरीके प्रदान करते हैं। बेशक, आपके डेटा को संग्रहीत करने के कई तरीके हैं। उदाहरण के लिए: एक डेटाबेस में, एक्सएमएल फ़ाइल में, एक सेवा पर,। इन संभावित तरीकों में से प्रत्येक के लिए, आप डेटा एजेंट चाहते हैं। अब समस्या यह है कि आप नहीं चाहते हैं कि कोई डेटाबेस डेटा के लिए DataAgentB के साथ XMLA फ़ाइलों के लिए DataAgentA का उपयोग करता है (मान लीजिए कि हमारे पास ए और बी इकाइयां हैं)। उपयोगकर्ता को केवल एक स्टोरेज इंजन का उपयोग करना चाहिए।

मुझे सार फैक्टरी पैटर्न पेश करने दें।

आप सुनिश्चित करेंगे कि उपयोगकर्ता सीधे आपके डेटा एजेंटों को तुरंत चालू नहीं कर सकते हैं, लेकिन उन्हें इन डेटा एजेंटों को कारखाने से बाहर करना होगा। (एक अतिरिक्त लाभ यह है कि, जब आप उदाहरण के लिए डेटाबेस (ईएफ) का उपयोग करते हैं, तो आप यह सुनिश्चित करने के लिए आंतरिक तारों को कर सकते हैं कि आपके डेटा एजेंट एक ही संदर्भ का उपयोग करते हैं, आदि) हम इसे कैसे पूरा कर सकते हैं? हमने अपने डेटा एजेंटों के निर्माता को 'अनंत' में स्थापित किया है। इसके अलावा, हम प्रत्येक स्टोरेज इंजन के लिए विभिन्न कारखानों का निर्माण करते हैं। अब, चूंकि उन कारखानों में सब कुछ समान है, इसलिए हमारे पास इन इंटरफेस भी हैं (बस हमारे डेटा एजेंटों की तरह, क्योंकि उन्हें सभी को ऐसा करना है, है ना ??)।

नीचे हमारे पास इंटरफेस हैं। असल में यह कारखाना पैटर्न है, लेकिन केवल कक्षाओं के बजाय, हम इंटरफेस के बारे में बात कर रहे हैं।

public interface IAgentA 
{
    // Add some methods here!
}

public interface IAgentB
{
    // Add some methods here!
}

public interface IAgentFactory
{
    IAgentA CreateAgentA();
    IAgentB CreateAgentB();
}

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

public class AgentA_Xml : IAgentA
{
    internal AgentA_Xml()
    { /* Construction here */}

    // IAgentA method implementations
}

public class AgentB_Xml : IAgentB
{
    internal AgentB_Xml()
    { /* Construction here */}

    // IAgentB method implementations
}


public class AgentA_Database : IAgentA
{
    internal AgentA_Database()
    { /* Construction here */}

    // IAgentA method implementations
}

public class AgentB_Database : IAgentB
{
    internal AgentB_Database()
    { /* Construction here */}

    // IAgentB method implementations
}

अब कन्स्ट्रक्टर आंतरिक हैं। इसका कारण यह है कि आप असेंबली के बाहर उन कक्षाओं को तुरंत चालू नहीं कर सकते हैं, जो आमतौर पर आप इस तरह के मामलों के साथ क्या करते हैं। अब हमें अपने कारखानों को बनाना है।

public class XMLAgentFactory : IAgentFactory
{
    public IAgentA CreateAgentA()
    {
        return new AgentA_Xml();
    }

    public IAgentB CreateAgentB()
    {
        return new AgentB_Xml();
    }
}


public class DatabaseAgentFactory : IAgentFactory
{
    public IAgentA CreateAgentA()
    {
        return new AgentA_Database();
    }

    public IAgentB CreateAgentB()
    {
        return new AgentB_Database();
    }
}

चूंकि दोनों कारखानों IAgentFactory इंटरफ़ेस को कार्यान्वित करते हैं, इसलिए उपयोगकर्ता आसानी से AgentFactory कार्यान्वयन को बदल सकता है (यदि वह, इस मामले में, एक अलग भंडारण इंजन का उपयोग करना चाहता है) बिना किसी अन्य कोड (एजेंटों के खिलाफ) को बदलने के बिना, जब तक उन्होंने इंटरफेस के खिलाफ प्रोग्राम किया (जाहिर है)।

उपरोक्त स्पष्टीकरण उम्मीद है कि आपके प्रश्नों का उत्तर दें (1) और (2)।

  1. सी # में सार कारखाने पैटर्न के लिए अच्छा उदाहरण?
  2. और सी # में सार कारखाने पैटर्न के क्या फायदे हैं?

आपके प्रश्न का उत्तर देना (3)।

  1. सार फैक्टरी पैटर्न के साथ सी # जेनेरिक का उपयोग कैसे करें?

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

आपके प्रश्न का उत्तर देना (4)।

  1. सार कारखाने पैटर्न के साथ इकाई परीक्षण कैसे करता है?

जैसे ही आप यूनिट किसी अन्य वर्ग का परीक्षण करेंगे। केवल एक चीज अलग होगी।

चूंकि आप शायद अपने वर्गों (और शायद अन्य आंतरिक तरीकों) के निर्माता का परीक्षण करना चाहते हैं, इसलिए आपको अपनी यूनिट टेस्ट प्रोजेक्ट में दिखाई देने वाले आंतरिक कन्स्ट्रक्टर (विधियों) को बनाने की आवश्यकता है (और आप internal को public बदलना नहीं चाहते हैं) । यह आपकी परियोजना की आपकी AssemblyInfo.cs फ़ाइल में निम्न पंक्ति जोड़कर आसानी से किया जाता है (वह परियोजना जहां आपका कारखाना और कक्षाएं हैं):

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")]

आप MSDN पर InternalsVisibleTo विशेषता के बारे में अधिक जानकारी (और टिप्पणियां) पा सकते हैं।

मुझे आशा है कि इस तरह के आपके प्रश्न का उत्तर दें।

  1. सी # में सार कारखाने पैटर्न के लिए अच्छा उदाहरण?
  2. सी # में सार कारखाने पैटर्न के क्या फायदे हैं?
  3. सार कारखाने पैटर्न के साथ सी # जेनेरिक का उपयोग कैसे करें?
  4. सार कारखाने पैटर्न के साथ इकाई परीक्षण कैसे करें?




abstract-factory