2009-11-16 10 views
5

फैक्टरी की मेरी समझ यह है कि यह कंक्रीट कक्षाओं के तत्कालता को समाहित करता है जो सभी एक सामान्य सार वर्ग या इंटरफेस का उत्तराधिकारी है। यह क्लाइंट को कौन सी ठोस कक्षा बनाने के लिए निर्धारित करने की प्रक्रिया से decoupled करने की अनुमति देता है, जिसका मतलब है कि आप क्लाइंट के कोड को बदलने के बिना अपने प्रोग्राम से कंक्रीट कक्षाओं को जोड़ या निकाल सकते हैं। आपको कारखाना बदलना पड़ सकता है, लेकिन कारखाना "उद्देश्य निर्मित" है और वास्तव में केवल बदलने का एक कारण है - एक ठोस वर्ग जोड़ा/हटा दिया गया है।क्या यह इस वर्ग को "फैक्ट्री" कहने में भ्रमित है?

मैंने कुछ कक्षाएं बनाई हैं जो वास्तव में ऑब्जेक्ट इंस्टेंटेशन को समाहित करती हैं लेकिन एक अलग कारण के लिए: ऑब्जेक्ट्स को तुरंत चालू करना कठिन होता है। फिलहाल, मैं इन वर्गों को "कारखानों" कह रहा हूं, लेकिन मुझे चिंता है कि एक गलत नामक हो सकता है और अन्य प्रोग्रामर को भ्रमित कर देगा जो मेरे कोड को देख सकते हैं। मेरा "कारखाना" वर्ग यह तय नहीं करता कि कौन सी ठोस कक्षा को तत्काल स्थापित किया जाए, वे गारंटी देते हैं कि वस्तुओं की एक श्रृंखला सही क्रम में तत्काल हो जाएगी और जब मैं new() पर कॉल करता हूं तो सही कक्षाएं सही रचनाकारों में पारित की जाएंगी।

उदाहरण के लिए, एक एमवीवीएम प्रोजेक्ट के लिए मैं काम कर रहा हूं, मैंने यह सुनिश्चित करने के लिए एक कक्षा लिखी है कि मेरा SetupView ठीक से तत्काल हो जाता है।

public class SetupViewFactory 
{ 
    public SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities) 
    { 
     var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities); 
     var setupView = new SetupView(); 
     setupView.DataContext = setupViewModel; 
     return setupView; 
    } 
} 

यह है कि यह एक "फैक्टरी" कॉल करने के लिए भ्रामक है: यह इस तरह दिखता है? यह कई संभावित ठोस कक्षाओं में से एक तय नहीं करता है, और इसका रिटर्न प्रकार इंटरफ़ेस या सार प्रकार नहीं है, लेकिन यह ऑब्जेक्ट इंस्टेंटेशन को समाहित करता है।

यदि यह "कारखाना" नहीं है, तो यह क्या है?


संपादित

लोगों ने सुझाव दिया है कि यह वास्तव में बिल्डर पैटर्न है।

dofactory से बिल्डर पैटर्न की परिभाषा इस प्रकार है:

अलग अपने प्रतिनिधित्व से एक जटिल वस्तु के निर्माण के लिए इतना है कि एक ही निर्माण की प्रक्रिया अलग अभ्यावेदन बना सकते हैं।

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


संपादित 2

मैं सिर्फ एक Wikipedia article on Dependency Injection में एक दिलचस्प उदाहरण मिल गया।

public class CarFactory { 

    public static Car buildCar() { 
     return new Car(new SimpleEngine()); 
    } 

} 

यह लगभग बिल्कुल उपयोग मेरे पास है (और, नहीं, मैं विकी लेख :) नहीं लिखा था) है:

के तहत "मैन्युअल रूप से इंजेक्शन निर्भरता", यह निम्नलिखित वर्ग शामिल हैं।

दिलचस्प है, इस लिए इस कोड निम्नलिखित टिप्पणी है:

उपरोक्त कोड में, कारखाने कार कोडांतरण की जिम्मेदारी लेता है, और कार में इंजन injects। यह कार को इंजन बनाने के बारे में जानने से मुक्त करता है, हालांकि अब कारफैक्टरी को इंजन के निर्माण के बारे में जानना है। कोई एक इंजन फैक्ट्री बना सकता है, लेकिन यह केवल कारखानों के बीच निर्भरता बनाता है। तो समस्या बनी हुई है, लेकिन कम से कम कारखानों, या निर्माता ऑब्जेक्ट्स में स्थानांतरित कर दिया गया है। [मेरे जोर]

तो, यह मुझसे कहता है कि कम से कम मैं केवल एक है जो एक वर्ग एक और वर्ग में सामान इंजेक्शन लगाने के साथ मदद करने के लिए बनाने के बारे में सोचा है नहीं कर रहा हूँ, और मेरे अलावा कोई और नहीं कर रहा हूँ का प्रयास किया इस वर्ग को एक कारखाने का नाम देने के लिए।

+2

नाइटपीकी न होने के लिए, लेकिन आप अपनी विधि का नाम बदल सकते हैं या तो बनाएं, या CreateSetupView। – Mathias

+0

यदि यह सब करने की आपकी कोशिश है तो यह वास्तव में पैटर्न में से कोई भी नहीं है, बस कुछ शीर्ष स्तर की कक्षा में सब कुछ नया करें। यह एक कारखाना हाँ कहना गलत है। – Chap

+0

उदाहरण कन्स्ट्रक्टर पैटर्न की तरह लगता है। –

उत्तर

4

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

  1. संबंधित/निर्भर वस्तुओं
  2. ठोस वर्ग है, वास्तव में, निर्दिष्ट
  3. का कोई परिवार नहीं है:

    GOF पैटर्न से सख्ती से परखने के बाद, मैं इसे दो कारणों के लिए फैक्टरी पर निशान याद करते हैं लगता है

बिल्डर के संबंध में, मुझे लगता है कि यह उत्पादों के भिन्नता के पहलू में याद आती है।

जब मैं डिज़ाइन पैटर्न पाठ्यक्रम पढ़ता हूं, तो मैं छात्रों को "सर्वोत्तम फिट" निर्धारित करने की कोशिश करते समय केवल पैटर्न के इरादे पर न देखने के लिए कहता हूं, बल्कि प्रयोज्यता और संरचना/प्रतिभागियों को देखता हूं। इरादा आपको चीजों पर शासन करने में मदद कर सकता है, लेकिन प्रयोज्यता & संरचना/प्रतिभागी हैं जो आपको घर में मदद करेंगे।

यदि आप पहचान सकते हैं कि आपके डिज़ाइन का कौन सा हिस्सा प्रतिभागियों के विभिन्न भूमिकाओं को सार (सार) फैक्टरी या बिल्डर, फिर आपने उस नामकरण का उपयोग करने के लिए एक अच्छा मामला बनाया है।

+0

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

+0

@ क्रिस, भी, कृपया @Jeff शाश्वत के उत्तर पर एक टिप्पणी के लिए मेरी टिप्पणी देखें कि मैं केवल सेटअप व्यू के लिए एक कन्स्ट्रक्टर क्यों नहीं लिखता हूं। – devuxer

+0

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

1

GOF यह "Builder"

+0

जहां तक ​​मुझे पता है, एक बिल्डर को निदेशक और उत्पाद की आवश्यकता होती है –

+2

निदेशक क्लाइंट कोड है, और उत्पाद स्पष्ट रूप से एक सेटअप व्यू है। –

1

मुझे लगता है, यह एक "फैक्टरी" है कहते हैं। जब मैं कक्षा घोषणा को देखता हूं, तो मुझे यह देखकर खुशी हो रही है कि यह एक "फैक्टरी" है, और और भी, यह SetupView ऑब्जेक्ट्स का "फैक्टरी" है। तो मुझे पता है कि यह फैक्टरी मुझे कंक्रीट और सही ढंग से सेटअप सेटअप उदाहरण देगा।

4

यह आप वहाँ एक फैक्टरी पैटर्न की तुलना में एक Builder पैटर्न की अधिक है क्या है की तरह मुझे लग रहा है।

0

आप इसे "जादूगर" कह सकते हैं।

1

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

1

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

public class SetupView 
{ 
    public static SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities) 
    { 
     var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities); 
     var setupView = new SetupView(); 
     setupView.DataContext = setupViewModel; 
     return setupView; 
    } 
} 

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

को ओपी के टिप्पणी के जवाब में:

तो अलग होने के लिए इस तरह के एक की जरूरत मैं कोड के इस हिस्से में कहीं भी SetupViewModel बनाने से बचना होगा नहीं है। इसके बजाय बस SetupViewModel में प्रवेश करें, जिसे आप SetupViewModel के कन्स्ट्रक्टर को पास करने के लिए घटक गुणों के बजाय अपने सेटअप व्यू के साथ जोड़ना चाहते हैं। तो कोड बन जाता है ...

public class SetupView 
{ 
    public static SetupView CreateView(SetupViewModel model) 
    { 
     var setupView = new SetupView(); { DataContext = model }; 
     return setupView; 
    } 
} 
+1

@ जेसन जो निश्चित रूप से इसे फैक्ट्री पक्ष में लाएगा। आप CreateView को अलग-अलग कार्यक्षमता में विभाजित कर सकते हैं और अंतिम चरण सेटअपअप को वापस कर सकते हैं, जो बिल्डर की तरफ झुक जाएगा। मुझे लगता है कि यह निश्चित रूप से दोनों तरीकों से जा सकता है। – Joseph

+0

दिलचस्प विचार, लेकिन मेरे वर्तमान डिजाइन के साथ, मुझे लगता है कि SetupView और SetupViewModel के बीच एक वांछनीय अलगाव है। मैं अपने व्यू के साथ एक अलग व्यू मॉडेल का उपयोग करना चाहूंगा, जिसका अर्थ यह होगा कि मैं अपने व्यू के साथ गड़बड़ करने के बजाए सिर्फ एक और कारखाना (या कारखाना संपादित कर सकता हूं) बना सकता हूं। – devuxer

+0

@ जेसन, आपके उत्तर के अतिरिक्त धन्यवाद, लेकिन अब हम स्क्वायर वन पर वापस आ गए हैं :) मैं जो करने की कोशिश कर रहा हूं उसका पूरा बिंदु स्वचालित है और एक व्यूमोडेल बनाने, एक दृश्य बनाने की प्रक्रिया सुनिश्चित करने के लिए, DataContext, और एक दृश्य लौट रहा है जो "जाने के लिए तैयार है"।आपने जो किया है वह इस जिम्मेदारी का हिस्सा SetupView क्लास में ले जाया गया है, जो ठीक है (शायद यहां तक ​​कि अच्छा भी), लेकिन अब, जो भी वर्ग 'SetupView.CreateView()' को कॉल करने के लिए ज़िम्मेदार है, अभी भी एक नाम की आवश्यकता है। (और ध्यान दें, मेरे पास अन्य उदाहरण हैं जो इस से अधिक जटिल हैं।) – devuxer

0

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

1

सरल रचनाकारों के साथ दो वर्ग क्यों नहीं?

public class SetupViewModel { 
     public SetupViewModel(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities) { 
      this.DatabaseModel = databaseModel; 
      this.SettingsModel = settingsModel; 
      this.ViewUtilities = viewUtilities; 
     } 
} 

और

public class SetupView {   
     public SetupView(SetupViewModel model) {    
      this.DataContext = model; 
     } 
} 

इस तरह, दोनों वर्गों स्पष्ट रूप से राज्य है कि वे क्या जरूरत है का निर्माण किया जाना है।

+0

धन्यवाद, जेफ। यह लगभग वही है जो मेरे पास पहले से ही 'SetupViewModel' के लिए है। मेरे पास 'SetupView' नहीं है, जिसका अधिकांश डेटाकॉन्टेक्स्ट अधिकतर सेट है क्योंकि यह एमवीवीएम पैटर्न के लिए उपयोग नहीं किया गया सम्मेलन है। विचार यह है कि 'व्यू' को डिजाइनरों/कलाकारों द्वारा उत्पन्न किया जाना चाहिए, उदाहरण के लिए, अभिव्यक्ति मिश्रण, इसलिए कोड-पीछे में जितना संभव हो उतना छोटा कोड होना सर्वोत्तम है। साथ ही, आप DataContext को सेट करने वाले कोड को जोड़ने के बिना किसी भी समय एक नया दृश्य प्लग कर सकते हैं। – devuxer

+0

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

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