2013-10-07 3 views
6

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

मैं कोड के इस

var awcrap = new Extrude2013(); // BAD !!! 
awcrap.extrudify(); // I don't want to allow this 

बाकी अनुमति देने के लिए नहीं करना चाहती:

using System; 

namespace testie 
{ 
    public enum ExtrudeType { Extrude2013, Extrude2014 } 

    public interface IExtrudeStuff { 
     void extrudify(); 
    } 

    public class Extrude2013 : IExtrudeStuff { 
     public void extrudify(){ 
      Console.WriteLine ("extrudify 2013"); 
     } 
    } 

    public class Extrude2014 : IExtrudeStuff { 
     public void extrudify(){ 
      Console.WriteLine ("extrudify 2014"); 
     } 
    } 
    public static class ExtrudeFactory { 
     public static IExtrudeStuff Create(ExtrudeType t) { 
      switch (t) { 
       case ExtrudeType.Extrude2013: return new Extrude2013(); 
       case ExtrudeType.Extrude2014: return new Extrude2014(); 
       default: return null; 
      } 
     } 
    } 

    class MainClass { 
     public static void Main (string[] args) { 
      // Now for the pretty API part 
      var o = ExtrudeFactory.Create (ExtrudeType.Extrude2013); 
      o.extrudify(); 
      var p = ExtrudeFactory.Create (ExtrudeType.Extrude2014); 
      p.extrudify(); 

      var awcrap = new Extrude2013(); // BAD !!! 
      awcrap.extrudify(); // I don't want to allow this 
     } 
    } 
} 
+0

यह संभव नहीं है। 'नया 'कीवर्ड तत्काल अनुमति देगा। –

+0

क्यों न केवल उन्हें फैक्ट्री क्लास के अंदर निजी नेस्टेड कक्षाएं बनाते हैं? –

+0

क्या आप आंतरिक खोज रहे हैं? –

उत्तर

5

आप पूरी तरह से इस नामंज़ूर नहीं कर सकते। चाहे या नहीं यह एक भाषा "प्रतिबंध" है राय की बात होगी, लेकिन वहाँ चीजें हैं जो आप विचार कर सकते हैं कर रहे हैं:

  • निर्माता internal करें। यह कन्स्ट्रक्टर को कॉल करने के लिए घोषित असेंबली के भीतर किसी भी प्रकार की अनुमति देगा, लेकिन असेंबली के बाहर कुछ भी नहीं। इसका मतलब यह होगा कि कारखाने को कॉल करने के लिए उस असेंबली में आप जो भी कोड लिखते हैं, और इसका मतलब यह भी है कि आप किसी अन्य असेंबली में कक्षा के उपप्रकार घोषित नहीं कर सकते हैं, क्योंकि यह कन्स्ट्रक्टर को कॉल करने में असमर्थ होगा।
  • एक समान दृष्टिकोण वर्ग आप सार (या एक अंतरफलक) का पर्दाफाश, तो (कारखाने के एक उपवर्ग के रूप में या यहाँ तक कि private, क्योंकि यह कभी नहीं कारखाने के बाहर संदर्भित किया जाता था) एक internal घोषित बनाने के लिए किया जाएगा टाइप जो अमूर्त वर्ग या इंटरफेस लागू करता है।
  • एक टोकन की आवश्यकता है कि केवल कारखाने ही निर्माता में प्रदान कर सके। इस प्रकार DataTable वर्ग काम करता है। जबकि कन्स्ट्रक्टर अभी भी कहलाता है, उपयोगकर्ता को मूल्य के लिए null में पास करना होगा और कम से कम यह स्पष्ट होगा कि उन्हें ऐसा नहीं करना चाहिए।
+0

एक आवश्यकता टोकन सुरक्षित कैसे होगा? या संकलक द्वारा लागू? RequiredToken का प्रकार क्या है? –

+0

@ डेव: यह * आवश्यक * नहीं हो सकता है, इस अर्थ में कि उपयोगकर्ता अभी भी 'शून्य' पास कर सकता है। लेकिन यह रनटाइम पर असफल हो जाएगा और कोड को लिखने वाले व्यक्ति के लिए यह स्पष्ट होना चाहिए कि उन्हें इसे कॉल नहीं करना चाहिए। –

+0

@ डेव: यह भी ध्यान दें कि यदि आप जिन वर्गों का उपयोग कर रहे हैं वे सभी एक ही असेंबली में हैं, तो पहले दो दृष्टिकोण बेहतर होंगे। अंतिम दृष्टिकोण केवल तभी जरूरी है जब आपको परिभाषित असेंबली के बाहर परिभाषित उप-वर्गों की अनुमति देने की आवश्यकता हो। –

2

Factory Pattern के पूरे मुद्दे केवल फैक्टरी जानता है कि चुनते हैं और एक वस्तु बनाने के लिए कैसे है और यह केवल एक इंटरफेस नहीं एक ठोस वर्ग के माध्यम से instantiated वस्तु की कार्यक्षमता को उजागर करता है। ऑब्जेक्ट का कन्स्ट्रक्टर निजी बनाना विफल रहता है क्योंकि Factory स्वयं इसे तुरंत चालू नहीं कर सकता है।

समाधान:

1- एक interface वर्ग जो Extrude20XX कक्षाओं के सभी प्रकार लागू इस तरह के IExtrudeStuff के रूप में यह परिभाषित करें।

2- Extrude20XX कक्षा Factory के वर्ग के अंदर निजी नेस्टेड कक्षाओं के रूप में लपेटें।

3- सभी ExtrudeXX कक्षाओं में इंटरफेस IExtrude लागू करें।

4- लिखें (स्थिर) Create (t) विधि की तरह:

public static class ExtrudeFactory { 
public static IExtrudeStuff Create(ExtrudeType t) { 
{ 
    switch (t) { 
     case ExtrudeType.Extrude2013: return new Extrude2013(); 
     case ExtrudeType.Extrude2014: return new Extrude2014(); 
     default: return null; 
    } 
} 
} 
+0

यह समाधान, नेस्टेड उपclasses प्रतीत होता है। क्या अच्छा होगा कि Extrude2013 (जिसे तत्काल नहीं किया जा सकता) जैसे वर्गों के लिए अलग-अलग फाइलें हों, फिर उन वर्गों के लिए कारखाने के अंदर गुण हों जिन्हें * –

+0

@dave को तत्काल किया जा सकता है हालांकि यह एक अच्छा अभ्यास है, कक्षाओं को वितरित करना अलग-अलग फाइलों में तब तक कुछ भी नहीं बदलेगा जब तक वे एक ही असेंबली में न हों। मुख्य बात यह है कि उन्हें 'फैक्टरी' कक्षा के अंदर निजी होना चाहिए। इस तरह 'फैक्टरी' वर्ग आंशिक हो सकता है और कंक्रीट कक्षाओं के माध्यम से फैलता है। – Alireza

+0

हां पूरी तरह से यह कोड के परिचालन अर्थशास्त्र को नहीं बदलेगा, लेकिन अंतर पठनीयता –

संबंधित मुद्दे