2009-04-30 7 views
43

मैं थोड़ी देर के लिए फैक्टरी विधि निर्माण पैटर्न का उपयोग कर रहा हूं। मैं अभी हाल ही में बताया गया था कि यह:क्या यह फैक्टरी विधि निर्माण पैटर्न है?

public static class ScheduleTypeFactory 
{ 
    public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 
    { 
     IScheduleItem scheduleItem = null; 

     switch (scheduleType) 
     { 
      case ScheduleTypeEnum.CableOnDemandScheduleTypeID: 
       { 
        scheduleItem = new VODScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.BroadbandScheduleTypeID: 
       { 
        scheduleItem = new VODScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.LinearCableScheduleTypeID: 
       { 
        scheduleItem = new LinearScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.MobileLinearScheduleTypeID: 
       { 
        scheduleItem = new LinearScheduleItem(); 
        break; 
       } 
     } 

     return scheduleItem; 
    } 
} 

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

+3

यह एक कारखाना है हालांकि बहुत सरल है। आमतौर पर फैक्ट्री का उपयोग जटिल निर्णय तर्क को समाहित करने के लिए किया जाता है और आपके मामले में निर्णय तर्क केवल enum lookup है। –

+4

फैक्टरी पैटर्न जटिलता को छिपाना है। एक enum की तलाश सरल है, लेकिन जब मैं इसे एक बार करता हूं, क्लाइंट के 10 गुना के बजाय, मैं इसे पसंद करूंगा। लेकिन मैं विधि को दोबारा शुरू करना शुरू कर दूंगा। कई लाइनें हैं, जिन्हें हटाया जा सकता है। – cRichter

+0

यह स्थैतिक कारखाना विधि है। इसका संदर्भ लें: http://stackoverflow.com/questions/929021/what-are-static-factory-methods –

उत्तर

30

निश्चित रूप से मेरे लिए कारखाने पैटर्न की तरह दिखता है। मुझे आपके कार्यान्वयन में कुछ भी गलत नहीं दिख रहा है।

Factory method pattern से

:।

फैक्टरी पैटर्न का सार " एक वस्तु बनाने के लिए एक इंटरफेस को परिभाषित करें, लेकिन उपवर्गों तय जो वर्ग का दृष्टांत को यह बताने के लिए है फैक्टरी विधि एक वर्ग की सुविधा देता है उप-वर्गों के लिए तत्कालता को रोकें। "

यह वही है जो आप कर रहे हैं।

एक साइड नोट के रूप में: अंगूठे का एक अच्छा नियम यह है कि जब भी कोई आपको कुछ बताता है और अपने बयान के लिए तर्क प्रदान करने में असमर्थ या अनिच्छुक है, तो एक अच्छा मौका है कि वे बयान देने के लिए अयोग्य हैं।

+10

"जब भी कोई आपको कुछ बताता है और अपने बयान के लिए तर्क प्रदान करने में असमर्थ या अनिच्छुक है, तो एक अच्छा मौका है वे सभी क्यूएफटी – annakata

+1

पर बयान देने के लिए अयोग्य हैं, वह वास्तव में क्या कर रहा है? मुझे कोई सबक्लास यहां तय नहीं होता है, बस सबक्लास वापस लौटे। – Peter

+0

शायद हम यहां बिंदु खो रहे हैं, लेकिन मुझे उप-वर्गीकृत इंटरफेस भी नहीं दिख रहा है। –

14

हां यह एक कारखाना पैटर्न है। मेरी एकमात्र टिप्पणी यह ​​होगी कि आप enum मानों के लिए चुपचाप विफल हो जाते हैं जिन्हें आप विशेष रूप से संभाल नहीं सकते हैं। यही कारण है कि उम्मीद की जा सकती है, लेकिन मुझे लगता है कि

default: 
    throw new InvalidOperationException("Invalid Enum Value"); 
+0

वापस लौटने में क्या गलत है? –

+0

मैं अत्यधिक अनुशंसा करता हूं क्योंकि यह आपके सिस्टम को विस्तारित करने और कुछ याद करने पर बहुत स्पष्ट बनाता है। – JoshBerke

+1

+1 अमान्य ऑपरेशन अपवाद के लिए - सी # enum मानों के बहुत क्षमा कर रहा है और यह जानना अच्छा होगा कि कोई व्यक्ति उस अमान्य प्रकार के रूप में अमान्य मान में डाला गया है या नहीं। –

5

जैसे बयानों के अंत में निम्नलिखित मेरे लिए एक (मूल) कारखाने की तरह लग रहा जोड़ने के लिए ... कई कारखानों में कार्यान्वयन अधिक जटिल है (शायद शामिल प्रकार का समाधान चाहते रनटाइम पर), लेकिन यह एक आवश्यकता नहीं है (AFAIK)। एकमात्र अन्य आलोचना जो मैंने जोड़ दी होगी, वह मामलों को गठबंधन करना है, और यदि आप इस प्रकार को पहचान नहीं पाते हैं तो कुछ और नाटकीय काम करें ...

0

यूप, यह कारखाना पैटर्न ठीक है। आपका टेक लीड गलत है।

2

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

+0

आपको क्यों लगता है कि यह रखरखाव योग्य नहीं है क्योंकि वह स्विच स्टेटमेंट का उपयोग कर रहा है? यह मेरे लिए पूरी तरह से बनाए रखने लगता है। –

+0

http://en.wikipedia.org/wiki/Factory_method_pattern एक उदाहरण में एक स्विच स्टेटमेंट दिखाता है। मुझे ठीक लगता है। –

+0

सरल मामलों में एक स्विच ठीक है और अधिक जटिल मामलों में इसे बनाए रखना मुश्किल हो सकता है; हालांकि, जब तक आपके पास जटिल मामले नहीं होते हैं, तब तक मैं सरल से चिपक जाता हूं। – JoshBerke

4

ठीक है, विकिपीडिया कहते हैं it is एक कारखाने विधि:

public class ImageReaderFactory 
{ 
    public static ImageReader getImageReader(InputStream is) 
    { 
     int imageType = figureOutImageType(is); 

     switch(imageType) 
     { 
      case ImageReaderFactory.GIF: 
       return new GifReader(is); 
      case ImageReaderFactory.JPEG: 
       return new JpegReader(is); 
      // etc. 
     } 
    } 
} 
0

मेरे लिए एक बुनियादी कारखाना पैटर्न की तरह लग रहा। मुझे यह जानकर उत्सुकता है कि आपका तकनीकी नेतृत्व क्यों नहीं सोचता कि यह एक पैटर्न है।

मैं भी dissapointed हूं कि वह चीजों को समझाने के लिए समय नहीं लेगी। एक टीम के सामने तकनीकी नेतृत्व होने के बाद, अपने फैसलों को समझाने के लिए समय निकालना महत्वपूर्ण है।

+3

मूल उत्तर होगा: उसका तकनीकी नेतृत्व एक मूर्ख है जो उसके गधे से बात कर रहा है। – TheTXI

+0

TheTXI: यह कहने के लिए धन्यवाद कि मैं क्या सोच रहा था :-) – JoshBerke

+0

जोश के साथ सहमत हुए। +1 –

8

मैं इसे पारंपरिक रूप से 'असली' Abstract Factory पैटर्न से अलग करने के सरल कारखाने पैटर्न कहा जाता है लगता है। ऐसा हो सकता है कि आप किसी प्रकार के आंतरिक नामकरण अभ्यास का पालन नहीं कर रहे हैं। हालांकि उसे खुद को समझाना चाहिए।

0

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

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

+0

मिमीएम, हेड फर्स्ट को काफी कुछ और विशेष रूप से किसी भी अकादमिक बहस में नहीं दिया जाता है। – Peter

4

फैक्टरी पैटर्न है, लेकिन यह आवश्यक रूप से सबसे अधिक रखरखाव संस्करण नहीं है। एक अधिक रखरखाव संस्करणScheduleTypeEnum मूल्यों और IScheduleItem के वास्तविक कंक्रीट उपप्रकारों के बीच कुछ प्रकार के वैश्विक मानचित्र को बनाए रखेगा - इस तरह, आप मानचित्र के लुकअप के साथ switch कथन को प्रतिस्थापित कर सकते हैं।

यह और अधिक रखरखाव क्यों है? क्योंकि उप-वर्ग लेखक साइट पर जोड़ों को जोड़ सकते हैं, जहां वे फ़ैक्टरी फ़ंक्शन के बजाए कक्षा कक्षा प्राप्त करते हैं। इसलिए बाद वाले को अद्यतन करने की आवश्यकता नहीं है; यह लगातार अद्यतित है।

सी में आप का उपयोग कर ऐसा कर सकते हैं ++ एक वैश्विक std::map - प्रत्येक ठोस उपवर्ग के लिए, उपवर्ग के लेखक एक डमी वैश्विक चर जो वास्तव में सिर्फ अपने निर्माता है, जो चलाता है में (मानचित्र को जोड़कर) वर्ग पंजीकृत करता है कहते हैं प्रोग्राम स्टार्टअप समय पर। मुझे यकीन है कि सी # में एक ही चीज़ करने का एक सुविधाजनक तरीका है।

(सी ++ गुरु हर्ब Sutter एक entertaining description here है, लेकिन यह काफी सी ++ है -। भारी)

0

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

4

मेरे लिए एक कारखाना पैटर्न की तरह दिखता है। अपने तकनीकी नेतृत्व को बताएं कि आपके पास यह समझाने का समय नहीं है कि वह गलत क्यों है।

-1

एक पाठ्यपुस्तक फैक्टरी पैटर्न है।

कुछ ग्रंथ इसे सरल फैक्ट्री पेटटेरेन कहते हैं, लेकिन मैंने कभी "सरल" साधनों के लिए कोई मानदंड नहीं देखा है।

मेरे अभ्यास में, फैक्ट्री पैटर्न एक वांछित इंटरफ़ेस के अनुरूप एक ठोस वर्ग का कोई बुद्धिमान निर्माण है।

लेकिन क्यों एक विधि नामकरण पर अपने तकनीकी नेतृत्व से लड़ें। इसका नाम बदलें, अपने जीवन के साथ आगे बढ़ें।

+1

पाठ्यपुस्तक? से किताब क्या है? निश्चित रूप से GoF या पहले सिर नहीं। – Peter

5

मुझे आश्चर्य है कि यह कारखाना पैटर्न है। (इसलिए संभावना है कि मैं इस गलत के बारे में सोच रहा हूं, इसलिए कृपया मुझे बताएं।)

ऐसा लगता है कि आपके पास केवल डिजाइन का एक हिस्सा है। यदि आप इसे अपने क्लाइंट से कहते हैं, तो इसे "सरल" फैक्ट्री के रूप में जाना जाता है, लेकिन इसे वास्तव में डिज़ाइन पैटर्न नहीं माना जाता है। (मुझे गलत मत समझो, मैं यह हर समय करता हूं)।

कारखाना डिजाइन पैटर्न यह बताएगा कि आपके कारखाने को एक अमूर्त कारखाना/कारखाना इंटरफेस विरासत/लागू करता है।

फिर, अपनी कक्षा में कारखाने (क्लाइंट) का उपयोग करने की आवश्यकता है, तो आप फैक्ट्री का प्रकार सार/कारखाने का निर्माण करते हैं, एक ठोस कारखाना बनाते हैं: यानी -> कारखाना कारखाना = नया कंक्रीट फैक्ट्री() ;

कंक्रीट फैक्ट्री तब आपके आईस्केड्यूल इटिम (इसे वास्तव में कंक्रीट प्रकार बनाने के लिए कारखाने में छोड़कर) बना देगा।

अंत में मुझे लगता है कि पूरा बिंदु ढीला युग्मन के बारे में है। जबकि एक "सरल" कारखाना ग्राहक से उत्पाद के निर्माण को कम करता है, यह कारखाने को कम नहीं करता है। कारखाने के पैटर्न कारखाने को भी decouples।

फिर, यह जल्दी है, मेरे पास कॉफी नहीं है, और मेरे पास पूरी तरह से भयानक प्रतिक्रिया पोस्ट करने की एक ग़लत आदत है जो प्रश्न के पूरे बिंदु को याद करती है।

+0

मैं बेकार है कि सार फैक्टरी पैटर्न – willcodejavaforfood

+0

http://en.wikipedia.org/wiki/Abstract_factory_pattern – user24985

+0

नहीं, यह सार फैक्टरी पैटर्न नहीं है, कोरी फैक्टरी विधि पैटर्न का वर्णन करता है, और यह काफी सही तरीके से करता है। सार फैक्ट्री अभी तक अमूर्तता की एक और परत है, जो * कारखानों को बनाने के लिए फैक्टरी विधि पैटर्न का उपयोग कर सकती है। –

0

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

बेशक, अक्सर आप अपनी कक्षा सार या इंटरफ़ेस बनाकर संकेत की एक परत जोड़ना चाहते हैं।

यह बहुत सरल दृश्य है, लेकिन किसी भी तरह से, आप फैक्ट्री पैटर्न का उपयोग कर रहे हैं।

31

मैं विधि को "फैक्टरी विधि" कहने के लिए सहमत हूं, हालांकि डिजाइन सख्ती से "फैक्टरी विधि पैटर्न" नहीं है।
यहाँ एक मुख्य बिंदु (विकिपीडिया से) है:

... फैक्टरी विधि के बाद से अपनी कक्षा स्थिर है और विधि स्थिर (इसलिए गैर उपवर्गों एक वर्ग आस्थगित करें इन्स्टेन्शियशन देता है "

। आभासी), वहाँ है कि इस कार्यान्वयन, हालांकि, कैप्सूलीकरण प्रदान करता है दसगुणा नहीं है/देरी कोई भी निर्णय कोई "टाल" संभव।

वैचारिक रूप से, नोटिस भी।

हवलदार आईएनजी ने कहा कि, वही विकिपीडिया लेख "स्कीम विधि पैटर्न" के संस्करण के रूप में इस स्कीमा को प्रस्तुत करता है।

सारांश की

सारांश: "। उपवर्गों एक वर्ग आस्थगित करें इन्स्टेन्शियशन" मेरी राय में इस स्निपेट, एक उचित "फैक्टरी विधि OO डिजाइन पैटर्न" के कार्यान्वयन नहीं है, क्योंकि यह संतुष्ट नहीं करता हालांकि, व्यक्तिगत रूप से मैं इस समाधान को "फैक्ट्री विधि" के रूप में स्वतंत्र रूप से संदर्भित करता हूं।

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

+2

यह क्यों है कि सही उत्तरों को इतने कम वोट मिलते हैं? – Peter

+0

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

+0

यह एक अच्छा जवाब है। मैं [हेड फर्स्ट डिज़ाइन पैटर्न] के माध्यम से पढ़ रहा हूं (http: //www.amazon।कॉम/फर्स्ट-डिज़ाइन-पैटर्न-एलिज़ाबेथ-फ्रीमैन/डीपी/0596007124) और यह एक "सरल फैक्ट्री" को परिभाषित करता है जो ओपी ने जो प्रस्तुत किया है उसके समान है, लेकिन यह स्पष्ट है कि कारखाने विधि विधि के "उचित" कार्यान्वयन subclasses द्वारा ओवरराइड करने के लिए एक अमूर्त कारखाने विधि की आवश्यकता है। मुझे समझ में परेशानी हो रही है, हालांकि, subclasses का उपयोग विरासत पर संरचना के पक्ष में कैसे करता है। –

12

आपका कोड खंड Head First Design Patterns में "द सरल फैक्टरी" (पृष्ठ 117) कहा जाता है।
Factory Method Pattern का मुख्य अंतर कंक्रीट क्रिएटर (ऊपरी दाएं कोने में चित्र की तुलना करें), जो आपके मामले में एक साधारण श्रेणी है।
"वास्तविक पैटर्न" में कारखाना वर्ग एक सार कारखाना वर्ग के साथ सार है। तो, एक और अमूर्त स्तर है। हालांकि, कई उपयोग मामलों के लिए, आपकी सरल फैक्टरी पर्याप्त है।

सरल फैक्टरी Simple Factory http://yuml.me/7221a4c9 फैक्टरी विधि पैटर्न Factory Method Pattern http://yuml.me/3d22eb4e

+0

इन आरेखों को उत्पन्न करने के लिए आपने किस टूल का उपयोग किया था? मुझे स्केची देखो और महसूस पसंद है। –

+9

यह yUML है: http://yuml.me यह बहुत ही बढ़िया है, आप पाठ द्वारा यूएमएल उत्पन्न करते हैं (उदाहरण के लिए [ग्राहक] +1 -> * [ऑर्डर]) और परिणाम एक साधारण लिंक के साथ एक छवि या पीडीएफ के रूप में प्रस्तुत किया जाता है इस तरह: http://yuml.me/5f1fa3ba जिसे आप किसी भी सामग्री में शामिल कर सकते हैं, उदाहरण के लिए। Ice09

8

आपका नेतृत्व सही (स्वरूपण के लिए खेद है, लेकिन इस सवाल का जवाब मुख्य लाइन है कि बताते हुए के बीच देखा जा करने के लिए इसके बारे में कुछ की जरूरत है लीड एक मूर्ख है): न तो जीओएफ पुस्तक और न ही हेड फर्स्ट द्वारा यह एक फैक्ट्री विधि है।

GOF:

"एक वस्तु बनाने के लिए एक इंटरफेस को परिभाषित करें, लेकिन जाने उपवर्गों जो वर्ग का दृष्टांत का फैसला। फैक्टरी विधि एक वर्ग उपवर्गों इन्स्टेन्शियशन स्थगित करने देता है। "

अपने उदाहरण में, यह एक उपवर्ग कि तय करना है कि नहीं है।

क्या आपने इन सभी वर्षों में गलत तरीके से इसे लागू किया है? नहीं, आपने अभी कारखाने के पैटर्न को लागू नहीं किया है, लेकिन कभी-कभी 'सरल फैक्टरी पैटर्न' के रूप में जाना जाता है, जिसने शायद नौकरी ठीक कर दी है।

0

आपका टेक विधि का नाम बदलने पर सही है:

public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 

विधि की कार्रवाई, कुछ पाने के लिए नहीं है बनाने कुछ। आप कैसे तय करते हैं कि कौन सा शेड्यूल टाइप किया जाना चाहिए? ऐसा लगता है कि तर्क को प्रकार के स्विच को encapsulated किया जाना चाहिए।

इसके अलावा कक्षा में स्थिर क्यों? आप इसका उपयोग कहां से कर रहे हैं?

public class ScheduleTypeFactory 
{ 
    public static IScheduleItem createScheduleFrom(ScheduleTypeEnum scheduleType) 
    { 

     switch (scheduleType) 
     { 
      case ScheduleTypeEnum.CableOnDemandScheduleTypeID: 
      case ScheduleTypeEnum.BroadbandScheduleTypeID: 
       return new VODScheduleItem(); 
      case ScheduleTypeEnum.LinearCableScheduleTypeID: 
      case ScheduleTypeEnum.MobileLinearScheduleTypeID: 
        return new LinearScheduleItem(); 
     } 

     raise InvalidSchedule; 
    } 
}