2011-08-13 8 views
5

मैं बेहतर टेस्टेबिलिटी और लूसर युग्मन के लिए आईओसी, डीआई और ओओडी के साथ बेहतर होने की कोशिश कर रहा हूं।आईओसी कंटेनर का उपयोग करते हुए ओओडी - निर्भर वस्तुओं का निर्माण कैसे करें?

तो जब हम आईओसी और डि का भारी इस्तेमाल के साथ कक्षाएं डिजाइन हम उदाहरण

class Processor 
{ 
    private IService1 m_Service1; 
    private IService2 m_Service2; 
    private IService3 m_Service3; 

    //approach 1 
    public Processor(IService1 service1, IService2 service2, IService3 service3) 
    { 
     m_Service1 = service1; 
     m_Service2 = service2; 
     m_Service3 = service3; 
    } 
    //approach 2 
    public Processor(IContainer container) 
    { 
     m_Service1 = container.Resolve<IService1>(); 
     m_Service2 = container.Resolve<IService2>(); 
     m_Service3 = container.Resolve<IService3>(); 
    } 

    //approach 3 
    public delegate Processor Factory(); 

} 

इम सोच क्या सामान्य दृष्टिकोण यहाँ होना चाहिए के लिए कई निर्भरता के साथ वर्गों के साथ endup कर सकते हैं। हम 3 मानकों के साथ निर्माता छोड़ सकते हैं, लेकिन हम autofac का उपयोग करके एप्लिकेशन (उदाहरण के लिए) सबसे अधिक संभावना का निर्माण कर रहे है, तो यह शायद ही कभी की तरह

Processor proc = new Processor(
container.Resolve<IService1>(), 
container.Resolve<IService2>(), 
container.Resolve<IService3>()); 

कुछ कंटेनर उदाहरण से प्रकार के समाधान तो मैं शायद दृष्टिकोण सोच रहा हूँ के अलावा किसी और का उपयोग किया जाएगा 2 बेहतर है, जब हम कंटेनर से कई प्रकारों पर निर्भर करते हैं। वैसे भी हमें कहीं ऑटोफैक का संदर्भ जोड़ना होगा, इसलिए अब कोई कारण नहीं है?

Autofac भी प्रदान करता है प्रतिनिधि कारखाने विधि दृष्टिकोण

http://code.google.com/p/autofac/wiki/DelegateFactories

var processorFactory = container.Resolve<Processor.Factory>(); 
Processor processor = processorFactory.Invoke(); 

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

चूंकि आईओसी के लिए काफी नया है, यह कहना मुश्किल है कि हमें 1,2,3 का उपयोग करना चाहिए। उनके पास फायदे और नुकसान हैं।

मुझे लगता है कि अगर कक्षा में 1 निर्भरता है तो हम शायद हमेशा दृष्टिकोण 1 का उपयोग कर सकते हैं .. इसके अलावा मुझे वास्तव में यकीन नहीं है कि क्या चुनना है और कब।

अद्यतन मैं सेवा लोकेटर विरोधी पैटर्न लेकिन Ive के बारे में पढ़ा है 4 (या सच 3 दृष्टिकोण)

छोड़कर

ServiceLocator करने के लिए अपने पास के साथ आते हैं अपनी नहीं है, हम एक वस्तु है कि इस

तरह लग रहा है पारित
public class ServiceLocatorObject 
{ 
     private IService1 m_Service1; 
     private IService2 m_Service2; 
     private IService3 m_Service3; 
     public IService1 Service1 {get {return m_Service1;}} 
     public IService2 Service2 {get {return m_Service2;}} 
     public IService3 Service3 {get {return m_Service3;}} 

     public ServiceLocatorObject(IService1 service1, IService2 service2, IService3 service3) 
     { 
      m_Service1 = service1; 
      m_Service2 = service2; 
      m_Service3 = service3; 
     } 
} 

और अब हम बनाने

//approach 4 
public Processor(ServiceLocatorObject servicesToUse) 
{ 
    m_Services = servicesToUse; 
} 

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

आप इस बारे में क्या कहेंगे?

उत्तर

6

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

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

यहां पढ़ा है: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx

मैं वास्तव में है कि तथ्य यह है कि विकल्प 1 में, प्रक्रिया स्पष्ट रूप से सेवाओं यह सूचियों निर्माता में मापदंड हैं में से प्रत्येक पर अपनी निर्भरता को व्यक्त करता है की तरह। यह निर्भरता को बहुत स्पष्ट बनाता है .... और आगे मुझे लगता है कि यह अच्छी डिजाइन को बढ़ावा देने में मदद करता है।

बस कह रहा है कि प्रोसेसर एक आईकॉन्टेनर लेता है हमें बहुत कुछ नहीं बताता है ... और इस प्रकार आपको परस्पर निर्भरताओं की पहचान करने के लिए बहुत करीब लगने की आवश्यकता है।

+0

लिंक अच्छा है, यह पुस्तक बिल्कुल वैसा ही दिखती है जो मुझे चाहिए। तीसरे दृष्टिकोण के बारे में आप क्या सोचते हैं? –

+0

+1 और टिप्पणियों के लिए मेरा उत्तर देखें। –

+1

मैं अपने कोड पर तीसरे दृष्टिकोण का उपयोग करता हूं ... जब मुझे समय के साथ एक प्रकार के कई उदाहरण बनाने के साधनों को इंजेक्ट करने की आवश्यकता होती है। मैं विंडसर का उपयोग करता हूं ... इसलिए मैं प्रतिनिधि कारखानों का बहुत उपयोग करता हूं, और Func इंजेक्ट करता हूं जब मुझे पता है कि मेरे प्रोसेसर को समय के साथ कई IService1s बनाने की आवश्यकता होगी ... – Jeff

0

यह निर्भरताओं की संख्या और न ही प्रति वर्ग निर्णय के बारे में है। दृष्टिकोण 2 एक नई निर्भरता पेश करता है, लेकिन यदि आप एक आईओसी कंटेनर पर भरोसा करना चाहते हैं, तो यह एक अच्छा दृष्टिकोण है। दृष्टिकोण 3 दूसरे की तरह है, लेकिन आप भविष्य में कारखाने में कुछ सामान करते हैं। दृष्टिकोण 1 सबसे सरल है, किसी भी चीज़ पर भरोसा नहीं करता है और उन निर्भरताओं के लिए उपयोग किया जाना चाहिए जिन्हें आप आमतौर पर आईओसी कंटेनर के माध्यम से प्रबंधित नहीं करेंगे।

+0

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

+0

आईओसी कंटेनर का उपयोग करने का विकल्प पूरे एप्लिकेशन को प्रभावित करता है - प्रत्येक मॉड्यूल पर निर्भर होना चाहिए। दृष्टिकोण 1 प्राकृतिक है - सभी डेवलपर्स इसे समझते हैं। दृष्टिकोण 2 कंटेनर विशिष्ट है। सबसे खराब चीज जो आप कर सकते हैं उन्हें मिश्रण करना है। कोड के पाठक को यह जांचना होगा कि परीक्षण के लेखक के लिए कौन सा एप्राच उपयोग किया जाता है। –

6

जवाब JeffN825 द्वारा दिए गए सही है, लेकिन मैं इसे में जोड़ने के लिए कि आप एक नया प्रोसेसर उदाहरण इस तरह एक कंटेनर का उपयोग कभी नहीं बनाएंगे चाहते हैं:

Processor proc = new Processor(
    container.Resolve<IService1>(), 
    container.Resolve<IService2>(), 
    container.Resolve<IService3>()); 

बल्कि, आप करते हैं चाहते हैं कंटेनर ऑटो तार निर्भरता और resolve it one go:

Processor proc = container.Resolve<Processor>(); 
+0

धन्यवाद, मार्क। क्या आप शायद तीसरे दृष्टिकोण के बारे में कुछ कह सकते हैं? परिस्थितियां क्या होती हैं जब आपके सुझाए गए प्रोसेसर proc = कंटेनर से बेहतर होता है। (); या पहला दृष्टिकोण? –

+1

तीसरा दृष्टिकोण छिपाने में सिर्फ एक सार फैक्टरी है: http://blog.ploeh.dk/2009/05/28/DelegatesAreAnonymousInterfaces.aspx यह वास्तव में दो अन्य दृष्टिकोणों से संबंधित नहीं है। आप इससे क्या करेंगे? –

+0

हे मार्क, आईव ने आपकी कुछ पोस्ट पढ़ने के बाद प्रश्न में एक अपडेट जोड़ा, आप इसके बारे में क्या सोचते हैं? –

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