2009-03-30 16 views
21

मैं एक अच्छा एक बिल्डर पैटर्न (सी # में) के उदाहरण के लिए ध्यान दिया है, लेकिन एक नहीं मिल सकता है, क्योंकि या तो मैं बिल्डर पैटर्न समझ में नहीं आता या मैं कुछ है कि था ऐसा करने के लिए कोशिश कर रहा हूँ कभी इरादा नहीं उदाहरण के लिए, यदि मेरे पास कार पार्ट्स बनाने के लिए एक अमूर्त ऑटोमोबाइल और अमूर्त बिल्डर विधियां हैं, तो मुझे अपने सभी 30 विकल्पों को निदेशक को भेजने में सक्षम होना चाहिए, क्या मुझे आवश्यक टुकड़े बनाना है, फिर मेरी ऑटोमोबाइल बनाएं। भले ही कौन सी कार, ट्रक, अर्ध, आदि का उत्पादन किया गया हो, मैं इसे उसी तरह से "ड्राइव" करने में सक्षम होना चाहिए।डिजाइन पैटर्न: बिल्डर

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

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

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

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

मुझे लगता है कि निदेशक केवल मुख्य कोड में मौजूद है। पैटर्न के भीतर केस स्टेटमेंट का उपयोग करने के बजाय स्वचालित रूप से यह निर्धारित करने का एक तरीका होना चाहिए कि कौन सी ठोस बिल्डर विधि पॉलिमॉर्फिज्म और विधि ओवरलोड (हालांकि यह एक बहुत बुरा उदाहरण है) के समान कॉल करने के लिए कॉल करें। (हर बार मुझे एक नया उत्पाद प्रकार जोड़ने की ज़रूरत है, मुझे मौजूदा निदेशक को संशोधित करने की आवश्यकता होगी, जो खराब है)।

+0

शायद, निर्माता पैटर्न में क्या गुम है, यह है कि ऑब्जेक्ट्स अंत में नष्ट नहीं होते हैं, इसलिए यदि आप पैटर्न को अनजान करते हैं तो मैं इसे बाद में जोड़ने का सुझाव देता हूं ... – Tobias

+0

वास्तव में आप जो चाहते हैं, लेकिन जांचें ये लेख:
[पैटर्न विवरण] (http://sourcemaking.com/design_patterns/builder)
[सी # कार्यान्वयन नमूना] (http://sourcemaking.com/design_patterns/builder/c%2523)
आशा है कि यह आशा है मदद करता है. – 0x49D1

उत्तर

10

मैं विकिपीडिया आलेख here में सी # उदाहरण का उल्लेख कर रहा हूं।

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

इस मामले में आपके पास पिज्जाबिल्डर को लागू करने वाला वर्ग होगा जो डेटाबेस से डेटा पुनर्प्राप्त करने के बारे में जानता है। आप इसे कई तरीकों से कर सकते हैं।

एक हवाईयन पिज्जाबिल्डर बन जाएगा। जब कक्षा शुरू होती है तो यह एक हवाईयन पिज्जा के लिए डेटाबेस से पूछताछ करता है और पंक्ति को पुनः प्राप्त करता है। फिर जब विभिन्न बिल्ड (एक्स) विधियों को बुलाया जाता है तो यह गुणों को पुनर्प्राप्त डेटाबेस पंक्ति के संबंधित फ़ील्ड में सेट करेगा।

कोई अन्य पिज्जाडेटाबेसबिल्डर बनाता है और यह सुनिश्चित कर लेता है कि जब आप कक्षा शुरू करते हैं तो आप उस प्रकार के पिज्जा के लिए आवश्यक पंक्ति की आईडी पास करते हैं।

waiter.PizzaBuilder = new HawaiianPizzaBuilder(); 

के बजाय उदाहरण के लिए आप का उपयोग

waiter.PizzaBuilder = new PizzaDatabaseBuilder("Hawaiian"); 

दूसरा समस्या मैं वास्तव में तो भागों बनाने के लिए उन्हें उत्पाद के लिए आवंटित करने के लिए बिल्डर तरीकों चाहते है, तार पारित नहीं लेकिन असली दृढ़ता से टाइप किया उत्पाद भागों।

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

बजाय

public override void BuildDough() { pizza.Dough = "pan baked"; } 
कुछ

आप क्या करेंगे

public override void BuildDough() { pizza.Dough = new DoughBuilder("pan baked"); } 

या

तरह
public override void BuildDough() { pizza.Dough = new PanBakedDoughBuilder(); } 

DoughBuilder अपने डेटाबेस में एक और मेज पर जा सकते हैं ठीक से एक PizzaDough को भरने के लिए कक्षा।

+0

अच्छा जवाब। यदि हम स्थाई रूप से घोषित फैक्ट्री कक्षाओं का उपयोग करते हैं, तो हमें नए ऑपरेटर की आवश्यकता नहीं होगी। टोबीकास्क का बिल्डर कॉल भी jQuery की तरह अद्भुत है। जवाब वह है जहां आपको निर्देशक की आवश्यकता नहीं होगी, मैं ये सब कुछ ले रहा हूं। यह चाल असली के लिए कोड करना होगा। आपका बहुत बहुत धन्यवाद। –

+0

जितना अधिक आप इस उत्तर को समझते हैं, उतना ही आपको एहसास होगा कि आरएस कॉनली कितनी जानता है। :) +100 अगर मैं कर सकता था। –

0

मैं कहूंगा कि आप इनमें से किसी से भी बच नहीं सकते हैं - आपके हिस्सों के लिए कुछ अधिभार हैं और स्टैक के नीचे कहीं भी मामला/अगर कथन है। नई कक्षा जोड़ते समय भी अपना कोड संशोधित करना आपका एकमात्र विकल्प हो सकता है।

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

उम्मीद है कि इससे मदद मिलती है।

19

ज्यादातर एक BuilderPattern की कॉल इस तरह दिखता है:

Car car = new CarBuilder().withDoors(4).withColor("red").withABS(true).build(); 
+2

यह डिजाइन पैटर्न द्वारा वर्णित बिल्डर पैटर्न वास्तव में नहीं है। पैटर्न को उसी स्रोत के विभिन्न प्रस्तुतिकरण बनाने के लिए डिज़ाइन किया गया है। उदाहरण के लिए, एक संकलक जो एक पार्सर का उपयोग करता है लेकिन x86, x64, और जावा बाइट कोड के लिए अलग-अलग बैकएंड है। –

+4

यह डिज़ाइन पैटर्न द्वारा वर्णित बिल्कुल नहीं हो सकता है लेकिन यह सुनिश्चित करता है कि बनाए गए ऑब्जेक्ट में सभी गुण सही ढंग से सेट हो जाएं। आप ऑब्जेक्ट बिल्डर को एक धाराप्रवाह इंटरफ़ेस का उपयोग भी कर सकते हैं ... लेकिन यह एक और प्रश्न – Kane

10

मैं इस तरह से इसके बारे में कभी नहीं सोचा था की है, लेकिन LINQ (पैटर्न, नहीं सिंटेक्स) वास्तव में एक बिल्डर, सही है?

यह एक धाराप्रवाह इंटरफ़ेस है जो एक क्वेरी बनाता है और विभिन्न प्रस्तुतियों में क्वेरी बना सकता है (एसक्यूएल, इन-मेमोरी ऑब्जेक्ट क्वेरीज, webservice प्रश्न, बार्ट डी स्मेट ने लिंक-टू-एक्सेल के कार्यान्वयन को भी लिखा है)।

+0

हां, बिल्कुल। –

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