2013-01-23 31 views
6

मुझे यहां थोड़ा पैटर्न दिशा चाहिए। सी # के लिए नया।दो तृतीय पक्ष वर्गों के लिए सामान्य इंटरफ़ेस मैं नियंत्रण नहीं करता हूं। बाहरी बहुरूपता?

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

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

using ThirdParty.TypeA.Employee; 
using ThirdParty.TypeB.Employee; 

public class Employee 
{ 
    private object genericEmployee; 

    private EmployeeType empType; 

    public enum EmployeeType 
    { 
      TypeA = 0; 
      TypeB = 1; 
    } 

    public Employee(Object employee, EmployeeType type) 
    { 
     genericEmployee = employee; 
     empType = type; 
    } 

    public String Name 
    { 
     if (empType == EmployeeType.TypeA) 
      return (ThirdParty.TypeA.Employee)genericEmployee.Name; 
     else 
      return (ThirdParty.TypeB.Employee)genericEmployee.Name; 
    } 

    public String Age 
    { 
     if (empType == EmployeeType.TypeA) 
      return (ThirdParty.TypeA.Employee)genericEmployee.Age; 
     else 
      return (ThirdParty.TypeB.Employee)genericEmployee.Age; 
    } 
} 

रेव 2:

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter 
{ 
    TypeA _employee; 
    public EmployeeTypeAAdapter(TypeA employee) 
    { 
     _employee = employee 
    } 

    public String Name 
    { 
     get { return _employee.Name; } 
     set { _employee.Name = value; } 
    } 

     public String Balance 
     { 
     get 
     { 
      if (_employee.Balance != null) 
      { 
       decimal c = _employee.Balance.Amount; 
       return String.Format("{0:C}", c); 
      } 
      else 
      { 
       return ""; 
      } 
      } 
     } 

     //... 
} 

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter 
{ 
    TypeB _employee; 
    public EmployeeTypeAAdapter(TypeB employee) 
    { 
     _employee = employee 
    } 

    public String Name 
    { 
     get { return _employee.Name; } 
     set { _employee.Name = value; } 
    } 

     public String Balance 
     { 
     get 
     { 
      if (_employee.Balance != null) 
      { 
       decimal c = _employee.Balance.Amount; 
       return String.Format("{0:C}", c); 
      } 
      else 
      { 
       return ""; 
      } 
      } 
     } 

    //.... 
} 
+0

टाइप ए और टाइपबी सार्वजनिक और जाने-माने हैं, मेरा मतलब है कि आपको वास्तव में enum पेश करने की आवश्यकता है? आप एक सामान्य तरीका जा सकते हैं। – abatishchev

+0

टाइपए और टाइपब के प्रकार क्या हैं, कक्षाएं कैसे घोषित की जाती हैं? गुणों के बराबर सेट और कोई बेस क्लास? तो आप उन्हें केवल 'ऑब्जेक्ट' द्वारा सामान्यीकृत कर सकते हैं? – abatishchev

+0

तीसरे पक्ष पुस्तकालय में कोई आधार वर्ग नहीं है। Enum केवल एक सुविधाजनक संपत्ति थी जिसे मैंने टाइपऑफ या आईएस का उपयोग करने के लिए ऑब्जेक्ट (टाइप ए या टाइपबी) के प्रकार को निर्धारित करने के लिए हर बार जब मैंने किसी संपत्ति का उपयोग किया था, का उपयोग करने से बचने के लिए बनाया था। – RyanMac

उत्तर

8

इस दृष्टिकोण का प्रयास करें:

public interface IEmployeeAdapter 
{ 
    string Age { get; set; } 
    string Name { get; set; } 
} 

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter 
{ 
    public EmployeeTypeAAdapter(TypeA employee) { } 
} 

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter 
{ 
    public EmployeeTypeBAdapter(TypeB employee) { } 
} 

public static class EmployeeAdapterFactory 
{ 
    public static IEmployeeAdapter CreateAdapter(object employee, EmployeeType type) 
    { 
     switch (type) 
     { 
      case EmployeeType.TypeA: return new EmployeeTypeAAdapter((TypeA)employee); 
      case EmployeeType.TypeB: return new EmployeeTypeBAdapter((TypeB)employee); 
     } 
    } 

    // or without enum 

    public static IEmployeeAdapter CreateAdapter(object employee) 
    { 
     if (employee is TypeA) return new EmployeeTypeAAdapter((TypeA)employee); 
     if (employee is TypeB) return new EmployeeTypeABdapter((TypeB)employee); 
    } 

    // or better introduce sort of type map 
} 

एक और उचित नाम EmployeeProxy, के रूप में आप पसंद करते हैं है।

+0

क्या मैं ऊपर वर्णित एडेप्टर में गुण वापस कर दूंगा? यह ध्यान में रखते हुए कि दो ऑब्जेक्ट्स (टाइपए और टाइपबी) 99% समान हैं (30 गुणों/विधियों में से एक या दो अलग-अलग नाम हो सकते हैं), और केवल वास्तविक अंतर में टाइप करें (एक थर्डपार्टी एडेप्टर टाइप प्रकार है। कर्मचारी और दूसरा थर्डपार्टी एडाप्टर है। टाइप बी। कर्मचारी) यह प्रतीत होता है कि लगभग डुप्लिकेट कक्षाएं बनती हैं। उपरोक्त रेव 2 देखें। – RyanMac

+0

@RyanMac: तो कठिनाइयों क्या है? क्षमा करें आप का पालन नहीं करते हैं। आप सभी साझा गुणों को इंटरफेस में डाल देते हैं, इसे स्वचालित रूप से लागू किया जाएगा। यदि अंतर्निहित प्रकार और इंटरफ़ेस में कोई संपत्ति नाम अलग है तो आप इसे ठीक से लागू/मिलान करने के लिए "सहायता" कर सकते हैं। – abatishchev

+0

@RyanMac: आप साझा गुणों और अन्य सहायक विधियों सहित एक सार आधार वर्ग भी पेश कर सकते हैं – abatishchev

2

जो आप करने की कोशिश कर रहे हैं उसे Duck typing के रूप में जाना जाता है। आप एडाप्टर कक्षाओं और साझा इंटरफेस का उपयोग करके ऐसा कर सकते हैं, लेकिन इन एडेप्टर बनाने के लिए मैन्युअल रूप से दोहराए जाने वाले गोंद कोड की आवश्यकता होती है। एक तरह से आप गोंद कोड लिखने के आसपास प्राप्त कर सकते हैं एडाप्टर प्रकार गतिशील रूप से निर्माण करना है। आप इसे आईएल एमिट के माध्यम से कर सकते हैं (एक सार्थक व्यायाम अगर आपको पहले कभी इसके साथ खेलने का मौका नहीं मिला है, हालांकि विचार करने के लिए कुछ सीमाएं हो सकती हैं।) यदि आप इसे काम करने में रुचि रखते हैं, हालांकि, आप शुरू करने के लिए this project को देख सकते हैं। सी # 'गतिशील' प्रकार का भी उपयोग किया जा सकता है (और दृश्यों के पीछे एक ही कोड पीढ़ी को कुछ करने के लिए हवाएं), लेकिन यह आपको एक संदर्भ नहीं देता है जिसे आप गैर गतिशील कोड के आसपास पास कर सकते हैं जैसे कि यह एक इंटरफ़ेस था प्रकार।

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

  • कोई संबंधित समस्या नहीं^_^