2009-07-28 15 views
12

मैं एक इंटरफ़ेस वापस करना चाहता हूं और एक स्विच स्टेटमेंट के अंदर मैं इसे सेट करना चाहता हूं। क्या यह एक खराब डिजाइन है?एक फैक्टरी विधि में लागू एक स्विच स्टेटमेंट है? सी #

private IResultEntity GetEntity(char? someType) 
    { 
     IResultEntity entity = null; 

     switch (someType) 
     { 
      case 'L': //life 
       entity = new LifeEntity(); 
       break; 
      case 'P': //property 
       entity = new PropertyEntity(); 
       break; 
      case 'D': //disability 
       entity = new DisabilityEntity(); 
       break; 
      case 'C': //credit card 
       entity = new CreditCardEntity(); 
       break; 
     } 

     return entity; 
    } 

उत्तर

19

मुझे आमतौर पर फैक्ट्री में स्विच स्टेटमेंट्स दिमाग में नहीं लगता है, बशर्ते मैं उन सभी व्युत्पन्न कक्षाओं को समूहित और नियंत्रित कर सकूं जिन्हें मैं अपने कारखाने को पहले से बनाना चाहता हूं।

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

मैं कुछ और अधिक शक्तिशाली/बहुमुखी कारखाने कक्षाएं

एक अच्छा मध्यम जमीन दृष्टिकोण मैं आमतौर पर लेने के लिए एक स्थिर शब्दकोश < स्ट्रिंग, प्रत्येक कारखाने वर्ग के लिए प्रकार> रखना है बनाने पर यह अच्छा source for some more info पाया।

लोग

Factories.TypeRegistration.StaticDictionary.Add("somekey",typeof(MyDerivedClass)) 

किसी प्रकार का उपयोग कर "पंजी" कर सकते हैं अपने खुद के कार्यान्वयन (या बेहतर अभी तक, एक पंजीकरण विधि का उपयोग करें और StaticDictionary छिपाने)

तो फैक्टरी के एक आसान काम नहीं है तालिका में एक देखने प्रदर्शन से उदाहरण बनाकर:

Activator.CreateInstance(Factories.TypeRegistration.StaticDictionary["somekey"]); 
+0

का आरक्षित एनम मान होने के साथ ही मैं आमतौर पर एक कारखाने तक पहुंचता हूं, खासकर उन पुस्तकालयों में जहां क्लाइंट ऐप्स अपना स्वयं का कार्यान्वयन जोड़ना चाहते हैं। – Joon

+0

अधिक जानकारी लिंक के लिए वह स्रोत अब उपलब्ध नहीं है, किसी भी मौके पर कहीं और होस्ट किया जा रहा है? या कहीं कहीं समकक्ष पोस्ट है? –

+0

@ सैम हीक मैंने एक संग्रहित संस्करण – Lennart

1

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

3

मुझे नहीं पता कि आपके पास सी # में कौन सी संभावनाएं हैं, लेकिन अभी भी जगह पर स्विच करने की तुलना में फैक्ट्री विधि में एक स्विच होना बेहतर है। एक फैक्ट्री विधि में, एक स्विच सहनशील होता है - लेकिन बेहतर ढंग से इसे अच्छी तरह से दस्तावेज किया गया है।

+5

यह उत्तर काफी कुछ बताता है जो मैं कहने जा रहा था। मैं जोड़ूंगा कि आपके फैक्ट्री कार्यान्वयन में एकमात्र चीज जो मैं बदलूंगा वह यह है कि मैं कारखाने की कुंजी होने के लिए एक नालीदार चर के बजाय एक गणना का उपयोग करूंगा। – wtaniguchi

+0

मैं एक बेवकूफ चार को enum में कैसे परिवर्तित करूं? मुझे नहीं लगता था कि आप तारों या चार्जों का एक enum बना सकते हैं। मैंने सोचा कि वे संख्यात्मक मूल्यों का प्रतिनिधित्व करते हैं। – Hcabnettek

+1

निश्चित रूप से 'जादुई' चरित्र पर enum के साथ सहमत हैं। इसके अलावा, यदि आप शून्य को वापस करने के बजाय सही केस नहीं पा रहे हैं तो आप अपवाद फेंकना पसंद कर सकते हैं। मुझे लगता है कि सिर्फ एक वरीयता हो सकती है। – kevindaub

2

मुझे नहीं लगता कि इसमें कुछ भी गलत है। हां, स्विच कथन एक कोड गंध है, लेकिन मेरी पुस्तक में, वे इस तरह की स्थिति में ठीक हैं। इस तरह की चीजों को हासिल करने के लिए आप वास्तव में कुछ और कर सकते हैं।

3

मैं नहीं बल्कि प्रकार आप एक कॉन्फ़िग फ़ाइल में एक विशिष्ट मूल्य के लिए दृष्टांत करना चाहते हैं होगा। कुछ की तरह:

<TypeMappings>
< TypeMapping नाम = "जीवन" type = "Entities.LifeEntity, संस्थाओं"/>
< TypeMapping नाम = "संपत्ति" type = "Entities.PropertyEntity, संस्थाओं"/>
< TypeMapping नाम = "विकलांगता" type = "Entities.DisabilityEntity, संस्थाओं"/>
< TypeMapping नाम = "क्रेडिट कार्ड" type = "Entities.CreditCardEntity, संस्थाओं"/>
+०१२३५१६४१०६</TypeMappings >

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

namespace Entities 
{ 

public interface IResultEntity 
{ 
} 

public class LifeEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Life entity"); 
    } 
} 

public class PropertyEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Property Entity"); 
    } 
} 

public class CreditCardEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a CreditCard Entity "); 
    } 
} 

public class DisabilityEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Disability Entity"); 
    } 
} 

}

public static Entities.IResultEntity GetEntity(string entityTypeName,string fileName) 
{ 
    XDocument doc = XDocument.Load(fileName); 
    XElement element = doc.Element("TypeMappings").Elements("TypeMapping") 
           .SingleOrDefault(x => x.Attribute("name").Value == entityTypeName);   

    if(element == null) 
    { 
     throw new InvalidOperationException("No type mapping found for " + entityTypeName); 
    } 
    string typeName = element.Attribute("type").Value; 
    Type type = Type.GetType(typeName); 
    Entities.IResultEntity resultEntity = Activator.CreateInstance(type) as Entities.IResultEntity; 
    if(resultEntity == null) 
    { 
     throw new InvalidOperationException("type mapping for " + entityTypeName + " is invalid"); 
    } 
    return resultEntity; 
} 

    public static void Main() 
{ 
    try 
    { 
     Entities.IResultEntity result = GetEntity("life", @"c:\temp\entities.xml"); 
     Console.WriteLine(result); 

     result = GetEntity("property", @"c:\temp\entities.xml"); 
     Console.WriteLine(result); 

     result = GetEntity("disability", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);   

     result = GetEntity("creditcard", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);   

     result = GetEntity("foo", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);  

    } 
} 

डि चौखटे का एक बहुत आप एक अंतरफलक है कि आप मेटाडाटा के आधार पर क्वेरी कर सकता है के लिए कई पंजीकरण प्रदान करते हैं:

यहां कुछ नमूना कोड है। मेटाडेटा का उपयोग करके एमईएफ निर्यात करता है, इस पर this link देखें।

+0

लिंक किया है जो ओवरकिल जैसा दिखता है –

2

यह बुरा नहीं है, यह लगभग चार बाइबल के गैंग में एक उदाहरण (पैरामीटरेटेड फैक्टरी विधि) जैसा ही है।

मुझे लगता था कि स्विच स्टेटमेंट कोड गंध हैं, वे नहीं हैं, उनके पास ओओ भाषा में उनकी जगह है।

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