2009-03-10 20 views
132

जब कक्षाएं मॉडलिंग, आरंभ की पसंदीदा तरीका क्या है:कंस्ट्रक्टर्स बनाम फैक्टरी के तरीके

  1. कंस्ट्रक्टर्स, या
  2. फैक्टरी के तरीके

और क्या उनमें से या तो उपयोग करने के लिए विचार किया जाएगा ?

कुछ स्थितियों में, मुझे एक फैक्ट्री विधि पसंद है जो ऑब्जेक्ट का निर्माण नहीं किया जा सकता है। यह कोड साफ है। मैं आसानी से जांच सकता हूं कि कन्स्ट्रक्टर से अपवाद फेंकने के विपरीत, वैकल्पिक कार्रवाई करने से पहले लौटाया गया मूल्य शून्य नहीं है। (मुझे व्यक्तिगत रूप से अपवाद पसंद नहीं हैं)

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

इसके विपरीत मेरे पास उन वर्गों पर एक स्थिर फैक्ट्री विधि हो सकती है जो रिकॉर्ड नहीं मिलने पर शून्य हो जाएंगे।

इस मामले, कन्स्ट्रक्टर या फैक्ट्री विधि में कौन सा दृष्टिकोण बेहतर है?

उत्तर

60

Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides.

के पेज 108 फैक्टरी विधि पैटर्न जब

  • एक वर्ग की वस्तुओं के वर्ग की आशा नहीं कर सकते हैं का प्रयोग करें से यह बनाना होगा
  • एक वर्ग वस्तुओं निर्दिष्ट करने के लिए अपने उपवर्गों चाहता है यह
  • वर्ग कई सहायक उप-वर्गों में से एक के लिए प्रतिनिधि जिम्मेदारी बनाता है, और आप इस प्रतिनिधि को स्थानीयकृत करना चाहते हैं कि कौन सा सहायक सबक्लास प्रतिनिधि
  • है
+17

स्टेटिक फैक्ट्री विधि गोफ डिजाइन पैटर्न - फैक्टरी विधि पैटर्न से अलग है। http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java –

+0

कृपया GoF डिज़ाइन पैटर्न के फैक्टरी विधि पैटर्न से तुलना न करें। –

+80

यह मुझे कुछ भी नहीं बताता – Sushant

23

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

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

+13

तो, (टीडीडी शैली) आप रचनाकारों के साथ काम शुरू करने का सबसे आसान तरीका के रूप में शुरू करेंगे। और फिर एक बार जब आप कोड गंध प्राप्त करना शुरू करते हैं तो कारखानों को दोबारा प्रतिक्रिया दें (जैसे कंडीशनर तर्क यह निर्धारित करता है कि कौन सा कन्स्ट्रक्टर कॉल करना है)? – AndyM

+0

बिल्कुल @ एंडीएम –

145

खुद से पूछें कि वे क्या हैं और हमारे पास क्यों हैं। वे दोनों एक वस्तु का उदाहरण बनाने के लिए हैं।

ElementarySchool school = new ElementarySchool(); 
ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside 

अब तक कोई अंतर नहीं है। अब कल्पना करें कि हमारे पास विभिन्न स्कूल प्रकार हैं और हम एलिमेंटरीस्कूल का उपयोग हाईस्कूल (जो प्राथमिक तत्व से लिया गया है या समान इंटरफ़ेस आईएसस्कूल को एलिमेंटरीस्कूल के रूप में लागू करता है) से स्विच करना चाहते हैं।कोड परिवर्तन होगा:

HighSchool school = new HighSchool(); 
HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside 

एक इंटरफेस के मामले में हम होगा:

ISchool school = new HighSchool(); 
ISchool school = SchoolFactory.Construct(); // new HighSchool() inside 

अब अगर आप एक से अधिक स्थानों आप देख सकते हैं कि कारखाने पद्धति का उपयोग करके क्योंकि बहुत सस्ता हो सकता है में इस कोड है एक बार जब आप कारखाने की विधि बदलते हैं तो आप कर लेंगे (यदि हम इंटरफेस के साथ दूसरे उदाहरण का उपयोग करते हैं)।

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

ISchool school = SchoolFactory.ConstructForStudent(myStudent); 

अब आप कि व्यापार तर्क क्या ISchool वस्तु अलग IStudent वस्तुओं के लिए दृष्टांत को निर्धारित करता है कि होता है अपने अनुप्रयोग में एक ही स्थान पर है।

तो - सरल वर्गों (मूल्य वस्तुओं, आदि) के लिए कन्स्ट्रक्टर ठीक है (आप अपने आवेदन को अतिरंजित नहीं करना चाहते हैं) लेकिन जटिल वर्ग पदानुक्रम कारखाने विधि के लिए एक पसंदीदा तरीका है।

इस तरह आप gang of four book से पहले डिजाइन सिद्धांत का पालन करते हैं "एक इंटरफ़ेस पर प्रोग्राम, कार्यान्वयन नहीं"।

+1

यहां तक ​​कि जब आपको लगता है कि यह एक साधारण वर्ग है, तो एक मौका है कि किसी को आपकी सरल कक्षा का विस्तार करने की आवश्यकता है, इसलिए फैक्ट्री विधि अभी भी बेहतर है। जैसे आप प्राथमिक स्कूल के साथ शुरू कर सकते हैं लेकिन बाद में कोई (स्वयं सहित) इसे निजी एलेमेंटरीस्कूल और पब्लिक एलिमेंटरीस्कूल के साथ बढ़ा सकता है। – jack

+5

यह स्वीकार्य उत्तर – am05mhz

+1

@ डेविड, अच्छा जवाब होना चाहिए, लेकिन क्या आप एक उदाहरण पर विस्तार कर सकते हैं जहां प्रत्येक इंटरफ़ेस कार्यान्वयन के निर्माण के लिए विभिन्न पैरामीटर की आवश्यकता हो सकती है। यहां एक मूर्ख उदाहरण है: 'आईफूड सैंडविच = नया सैंडविच (पनीर चेज, मांस मांस);' और 'आईफूड सूप = नया सूप (शोरबा शोरबा, सब्जी शाकाहारी);' कारखाने और निर्माता यहां कैसे मदद कर सकते हैं? –

11

केवल एक कारखाने का उपयोग करें जब आपको ऑब्जेक्ट सृजन के साथ अतिरिक्त नियंत्रण की आवश्यकता होती है, जिस तरह से रचनाकारों के साथ नहीं किया जा सकता है।

कारखानों में उदाहरण के लिए कैशिंग की संभावना है।

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

54

आपको पढ़ने की आवश्यकता है (यदि आपके पास पहुंच है) Effective Java 2आइटम 1: रचनाकारों की बजाय स्थिर फैक्ट्री विधियों पर विचार करें

स्टेटिक कारखाने तरीकों फायदे:

  1. वे नाम है।
  2. प्रत्येक बार जब उन्हें बुलाया जाता है तो उन्हें एक नई वस्तु बनाने की आवश्यकता नहीं होती है।
  3. वे अपने रिटर्न प्रकार के किसी उप-प्रकार का ऑब्जेक्ट वापस कर सकते हैं।
  4. वे पैरामीटरयुक्त उदाहरण उदाहरण बनाने की क्रिया को कम करते हैं।

स्टेटिक कारखाने तरीकों नुकसान:

  1. जब केवल स्थिर कारखाने के तरीकों, कक्षाएं सार्वजनिक या संरक्षित कंस्ट्रक्टर्स बिना प्रदान subclassed नहीं किया जा सकता।
  2. वे अन्य स्थिर तरीकों
+3

यह मुझे जावा में एक गंभीर बग, फिर एक सामान्य ओओडी समस्या लगता है। ऐसी कई ओओ भाषाएं हैं जिनके पास * कन्स्ट्रक्टर भी नहीं हैं, फिर भी सबक्लासिंग काम ठीक है। –

+0

@cherouvim क्यों अधिकांश कोड कन्स्ट्रक्टर्स का उपयोग करके लिखा जाता है यदि '(कारखाने के तरीके कन्स्ट्रक्टर्स से बेहतर होते हैं। (आइटम -1)) प्रभावी जावा ' – UnKnown

+0

अच्छे अंक। हालांकि यह जावा विशिष्ट है। एक भाषा सुविधा के लिए एक मामला बनाया जा सकता है जो फैक्ट्री विधियों को अन्य स्थिर तरीकों से अलग करने योग्य बनाता है। – OCDev

6

एक कैड/कैम आवेदन से एक ठोस उदाहरण से आसानी से अलग पहचाना नहीं हैं।

एक कन्स्ट्रक्टर का उपयोग करके एक काटने का मार्ग बनाया जाएगा। यह लाइनों और आर्कों की एक श्रृंखला है जो कटौती के पथ को परिभाषित करती है। जबकि रेखाओं और चापों की श्रृंखला अलग हो सकती है और एक ठेकेदार में एक सूची उत्तीर्ण करके इसे आसानी से संभाला जा सकता है।

एक कारखाने का उपयोग करके एक आकार बनाया जाएगा। चूंकि एक आकृति वर्ग होता है, जबकि प्रत्येक आकार किस प्रकार के आकार के आधार पर अलग-अलग सेटअप किया जाएगा। हम नहीं जानते कि जब तक उपयोगकर्ता चयन नहीं करता तब तक हम किस आकार को शुरू करने जा रहे हैं।

11

"प्रभावी जावा", दूसरा संस्करण, से एक उद्धरण, आइटम 1: रचनाकारों के बजाय स्थैतिक फैक्ट्री विधियों पर विचार करें, पी। 5:

"ध्यान दें कि एक स्थिर कारखाने विधि डिजाइन पैटर्न से फैक्टरी विधि पैटर्न के समान नहीं है [Gamma95, पी 107।] स्थिर कारखाने विधि यह आइटम में वर्णित में कोई सीधा बराबर है। डिजाइन पैटर्न्स।"

3

कहें, मेरे पास एक कक्षा पर एक निर्माता है जो आईडी मान की अपेक्षा करता है। कन्स्ट्रक्टर डेटाबेस से वर्ग को पॉप्युलेट करने के लिए इस मान का उपयोग करता है।

यह प्रक्रिया निश्चित रूप से एक निर्माता के बाहर होना चाहिए।

  1. कन्स्ट्रक्टर को डेटाबेस तक नहीं पहुंचना चाहिए।

  2. कार्य और एक निर्माता के लिए कारण इनिशियलाइज़ डेटा सदस्यों है और के निर्माता में पारित कर दिया मानों का उपयोग वर्ग अपरिवर्तनीय की स्थापना।

  3. सब कुछ के लिए किसी और एक बेहतर दृष्टिकोण स्थिर कारखाने विधि या अधिक जटिल मामलों में एक अलग कारखाने या बिल्डर वर्ग का प्रयोग है।

Some constructor guide lines from Microsoft:

निर्माता में कम से कम काम करो। रचनाकारों को कन्स्ट्रक्टर पैरामीटर को कैप्चर करने के अलावा अन्य काम नहीं करना चाहिए। किसी भी अन्य प्रसंस्करण की लागत आवश्यक होने तक देरी होनी चाहिए।

और

अगर वांछित आपरेशन के अर्थ विज्ञान एक नया उदाहरण के निर्माण के लिए सीधे मैप नहीं एक निर्माता के बजाय एक स्थिर कारखाने विधि का उपयोग पर विचार करें।

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