2009-05-13 13 views
7

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

प्रत्येक पेय को स्वयं को ठीक से शुरू करने के लिए कुछ तर्कों की आवश्यकता होती है। इनमें से कुछ सभी पेय के लिए आम हैं; उदाहरण के लिए, उन्हें सभी को DrinkConfig तर्क की आवश्यकता हो सकती है।

लेकिन प्रत्येक पेय में भी अपनी अनूठी आवश्यकताएं हो सकती हैं। शायद शराब को खुद को शुरू करने के लिए एक सोमेलियर सहायक वस्तु की आवश्यकता होती है। बीयर को इसकी आवश्यकता नहीं है, लेकिन इसकी अपनी सहायक वस्तुओं की आवश्यकता हो सकती है।

तो मुझे फैक्ट्री विधि को क्या पास करना चाहिए? जब मैं इसे कॉल करता हूं, तो मेरे पास सभी सहायक वस्तुएं उपलब्ध हैं, इसलिए मैं उन्हें सभी कारखाने में पास कर सकता हूं। लेकिन यह बहुत सारे तर्क होने का अंत हो सकता है। क्या इसे डिजाइन करने का कोई बेहतर तरीका है?

संपादित करें: मान लीजिए कि मैं कारखाने में सहायक वस्तुएं नहीं बना सकता; वे केवल कॉलर से उपलब्ध हैं।

उत्तर

4

मैं आपके कारखाने वर्ग में अलग अधिभार विधियां तैयार करूंगा।

public class DrinkFactory { 

    public static Drink CreateBeer(DrinkConfig config, string hops) { 
     return new Beer(config, hops); 
    } 

    public static Drink CreateWine(DrinkConfig config, string grapes, int temperature) { 
     return new Wine(config, grapes, temperature); 
    } 
} 

संपादित करें:

यह केवल फैक्टरी वर्ग में एक भी विधि के लिए के लिए वांछित है, तो एक विकल्प के कार्यान्वयन होगा:

public enum DrinksEnum { 
    Beer, 
    Wine 
} 

public class DrinkFactory { 

    public static Drink CreateDrink(DrinksEnum drinkType, DrinkConfig config) { 
     switch(drinkType) { 
      case DrinksEnum.Beer: 
       return new Beer(config); 
      case DrinksEnum.Wine: 
       return new Wine(config); 
      default: 
       throw new ApplicationException("Drink type not recognised."); 
     } 
    } 
} 
+0

हस्ताक्षर ठीक हैं। समस्या यह है कि आप अपने फैक्ट्री :: CreateDrink() (या जिसे भी कहा जाता है) में तर्कों में आप कैसे पास करते हैं। – dirkgently

+0

यदि आप कारखाने में CreateDrink विधि बनाना चाहते हैं तो आप यह निर्दिष्ट करने के लिए एक enum पैरामीटर का उपयोग कर सकते हैं कि आप कौन सी पेय प्रकार चाहते थे। मुझे विश्वास नहीं है कि ऊपर या दृष्टिकोण गोफ फैक्ट्री पैटर्न का अनुपालन करता है, जहां ऑब्जेक्ट्स ड्रिंक क्लास में बनाई जाती है (मुझे आज रात मेरी पुस्तक की जांच करनी है), लेकिन मुझे यह और अधिक व्यावहारिक लगता है और यह अभी भी प्राथमिक लाभ को बनाए रखता है उप वर्ग पदानुक्रमों के लिए ऑब्जेक्ट सृजन को केंद्रीकृत करना। – sipwiz

+0

मेरी गोफ डिज़ाइन पैटर्न बुक की जांच करने के बाद मुझे खुशी है कि मैंने जो उदाहरण दिया है वह सार फैक्ट्री डिज़ाइन पैटर्न के हिस्से के रूप में फैक्ट्री का उपयोग करने के करीब है। पूरी तरह से अनुरूप होने के लिए वहां एक अमूर्त फैक्ट्री क्लास होना चाहिए जो पेय पदार्थों से प्राप्त होता है लेकिन इस तरह के साधारण मामलों के लिए मैं इसे सामान्य रूप से छोड़ देता हूं। यदि एक और ठोस कारखाने की आवश्यकता होती है तो यह पेय पदार्थों को दोबारा करने में काफी आसान होगा। – sipwiz

0

मैं जहां एक अनुभवहीन समाधान प्रदान करने के लिए परीक्षा रहा हूँ अपने सामग्री बेस श्रेणी 'पेय सामग्री' से ली गई हैं। आपको एक विशेष पेय के लिए इस्तेमाल होने वाले उप-वर्ग से मेल खाना पड़ेगा।

जाहिर है, आप सामग्री के लिए एक और कारखाना बनाने के लिए लुभाने के लिए प्रेरित हो सकते हैं - लेकिन इससे चिकन-अंडे की समस्या हो जाएगी।

0

आम तौर पर, इन विवरणों को छिपाने के लिए एक कारखाना विधि मौजूद है। एक महत्वपूर्ण सवाल यह है कि सोम्मेेलियर कहां से आता है - यदि ये सभी अन्य सहायक सिंगलटन हैं या किसी ज्ञात स्रोत से अधिग्रहित किया जा सकता है, तो फैक्ट्री को आवश्यक जानकारी प्राप्त करने और उन्हें ढूंढने के लिए तत्काल करें, ताकि आपके कॉलिंग कोड की आवश्यकता न हो इसके बारे में चिंता करने के लिए।

इसके अलावा, कई मामलों में, स्प्रिंग जैसे ढांचे का उपयोग कोड के बजाए कॉन्फ़िगरेशन फ़ाइल में इन रिश्तों का वर्णन करने के लिए किया जाएगा।

यदि आपको कॉलिंग कोड से रनटाइम पर मददगारों को वास्तव में पास करने की आवश्यकता है, तो मैं पेपर 'तर्क और परिणाम' (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.7565) पढ़ने का सुझाव देता हूं जो जटिल तर्कों के लिए एक सामान्य पैटर्न का वर्णन करता है। अनिवार्य रूप से, आप आवश्यक मानकों का एक मध्यवर्ती संग्रह तैयार करेंगे और कारखाने को पास करेंगे।

2

फैक्ट्री विधि को मूल्यों को बनाने के विवरणों को दूर करना चाहिए। तो आपको फैक्ट्री विधि में सहायक वस्तुओं को पारित नहीं करना चाहिए, फैक्ट्री विधि को उस सहायक सहायक वस्तु का निर्माण करना चाहिए जो उसे आवश्यक कन्स्ट्रक्टर को पास कर दे।

0

इस तरह के मामलों में, मैं आमतौर पर चर में गुजरने के बजाय अन्य समाधानों की ओर देखता हूं।

उदाहरण के लिए, आपके मामले में - WineFactory एक Sommelier की आवश्यकता होगी,, तो यह उचित शराब निर्माण कर सकते हैं -

इस क्रम निर्भरता इंजेक्शन के लिए एक महान उपयोग है। कुछ रूपों का एक निर्भरता इंजेक्शन ढांचा यह सब सरल, समझने योग्य और केवल प्रकार के काम को बिना इन गुणों को पारित करने की आवश्यकता के बिना कर देगा।

1

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

कहा जा रहा है कि, आप इसके बजाय सेट की ऑब्जेक्ट्स की एक सूची को उस गुणों की संख्या के बराबर पास कर सकते हैं, जिन्हें आप सेट करना चाहते हैं। तब प्रत्येक ऑब्जेक्ट उस मान का प्रतिनिधित्व करेगा जिसे आप उपयुक्त ऑब्जेक्ट के कन्स्ट्रक्टर में सेट करना चाहते हैं, जिस क्रम में आप इन चर सेट करना चाहते हैं। इसका नकारात्मक पक्ष यह है कि आपको कॉल करने से पहले कारखाने के बाहर एक सूची को प्रारूपित करना होगा, जो कि कुछ हद तक बेकार है।

0

यह Builder पैटर्न के लिए एक आदर्श मामला जैसा दिखता है। जटिल वस्तुओं को बनाने के लिए समान वस्तुओं को बनाने के लिए Factory पैटर्न का उपयोग करें, और Builder पैटर्न का उपयोग करें। इस समस्या के लिए Factory पैटर्न का उपयोग करने का प्रयास करने से विभिन्न वस्तुओं के लिए कई, भिन्न प्रारंभिक रचनाकार (विभिन्न संख्याओं/पैरामीटर के साथ) का कारण बन जाएगा।

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