क्या फैक्टरी पैटर्न ओपन / बंद सिद्धांत का उल्लंघन करता है?


14

क्यों यह शेपफैक्टरी सशर्त वक्तव्यों का उपयोग करता है यह निर्धारित करने के लिए कि किस वस्तु को तत्काल करना है। अगर हम भविष्य में अन्य वर्गों को जोड़ना चाहते हैं, तो हमें ShapeFactory को संशोधित करना होगा? यह खुले बंद सिद्धांत का उल्लंघन क्यों नहीं करता है?

फैक्टरी पैटर्न डिजाइन

शेपफैक्ट डिजाइन


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


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

@ArmonSafai: आप इस ब्लॉग पोस्ट को बहुत लिंक कर रहे हैं, लेकिन आप वास्तव में यह नहीं समझा रहे हैं। क्या हम सभी किसी भी तरह से अनभिज्ञ हैं? हमारे पास भी आपकी तरह ही Google है।
रॉबर्ट हार्वे

1
@RobertHarvey मैं इस ब्लॉग पोस्ट को यह दिखाने के लिए लिंक कर रहा हूं कि कैसे उस पृष्ठ में फ़ैक्टरी पैटर्न सशर्त का उपयोग कर रहा है
Armon Safai

जवाबों:


20

पारंपरिक वस्तु-उन्मुख ज्ञान ifबयानों से बचने और उन्हें एक अमूर्त वर्ग के उपवर्गों में गतिशील तरीकों के गतिशील प्रेषण के साथ बदलने के लिए है। अब तक सब ठीक है।

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

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


2
बहुत सारे ifएस के बिना फ़ैक्टरी पैटर्न बनाना पूरी तरह से संभव है । यह कैसे प्राप्त करने के लिए एक सरल उदाहरण के लिए @ B exampleовић का जवाब देखें। Downvoted।
डेविड अरनो


11
@DavidArno स्वाभाविक रूप से, ठोस वर्ग चुनने के अलग-अलग तरीके हैं। सेवा लोकेटर एक है, एक विन्यास योग्य आईओसी कंटेनर एक और है। वे केवल कार्यान्वयन विवरण हैं; वे किलरियन के मुख्य संदेश से अलग नहीं होते हैं, जो यह है कि फैक्ट्री कॉल करने वाले को यह तय करने से रोकती है कि किस ठोस वर्ग को त्वरित करना है। विवरण में मत जाओ।
रॉबर्ट हार्वे

1
भयानक बयान जो किसी भी तरह से सवाल का जवाब नहीं देता है।
मार्टिन मेट

1
@ R.Schmitz मुझे लगता है कि आप अपनी धारणा में गलत हैं। मुझे लगता है कि कई लोगों ने ओपी से इस सवाल को याद किया: "अगर हमें भविष्य में अन्य वर्गों को जोड़ना चाहते हैं तो हमें शेपफैक्ट को संशोधित करना होगा?" स्पष्ट रूप से, ओपी यह सोचकर भ्रमित है कि यह पैटर्न OCP का उल्लंघन करता है क्योंकि नई कार्यक्षमता जोड़ने के लिए, आपको मौजूदा कोड को संशोधित करना होगा। इस प्रश्न का सही उत्तर मेरे उत्तर में मिल सकता है। संक्षिप्त उत्तर: आप उस कोड को अकेले छोड़ देते हैं और आप अपनी मौजूदा कार्यक्षमता को EXTEND (संशोधित नहीं) के लिए एब्सट्रैक्ट फ़ैक्टरी पैटर्न लागू करते हैं। इस वजह से किलियन का उत्तर प्रश्न को संबोधित नहीं करता है।
hfontanez

5

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

भविष्य में एक नए उपवर्ग के लिए समर्थन जोड़ने के लिए सशर्त का विस्तार करना वास्तव में कड़ाई से बोलना खुले / बंद सिद्धांत का उल्लंघन होगा। "सही" समाधान एक ही इंटरफ़ेस के साथ एक नया कारखाना बनाना होगा। जैसा कि कहा गया हे / सी सिद्धांत के पालन हमेशा चुंबन और YAGNI जैसे अन्य डिजाइन सिद्धांतों के खिलाफ तौला जाना चाहिए।

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


क्या आप यह बता सकते हैं कि मानचित्र / विन्यास / रजिस्ट्री कैसे काम करेगी?
अरमान सफाई

@ArmonSafai: यहां एक उदाहरण है: jkfill.com/2010/12/29/self-registering-factories-in-c-sharp
जैक्सबी

स्व-पंजीकृत कारखाने हैं, AFAIK, स्थिर पुस्तकालयों के अंदर C ++ में असंभव है क्योंकि अप्रयुक्त (यानी ओडीआर-प्रयुक्त) वैश्विक चर टूलचिन द्वारा खारिज कर दिए जाते हैं।
vid.pointer

@ArmonSafai ने इसे और अधिक समझने के लिए पढ़ा goo.gl/RYuNSM
AZ_

2

पैटर्न स्वयं ओपन / बंद सिद्धांत (OCP) का उल्लंघन नहीं करता है। हालाँकि, हम OCP का उल्लंघन करते हैं जब हम पैटर्न का गलत तरीके से उपयोग करते हैं।

इस प्रश्न का सरल उत्तर इस प्रकार है:

  1. फैक्टरी विधि पैटर्न का उपयोग करके अपनी आधार कार्यक्षमता बनाएं ।
  2. सार फैक्ट्री पैटर्न का उपयोग करके अपनी कार्यक्षमता का विस्तार करें

दिए गए उदाहरण में, आपकी आधार कार्यक्षमता तीन आकृतियों का समर्थन करती है: सर्कल, आयत और वर्ग। मान लीजिए कि आपको भविष्य में त्रिभुज, पेंटागन और हेक्सागोन का समर्थन करने की आवश्यकता है। OCP का उल्लंघन किए बिना ऐसा करने के लिए , आपको अपनी नई आकृतियों (जिसे कहा जाता है AdvancedShapeFactory) का समर्थन करने के लिए एक अतिरिक्त कारखाना बनाना होगा और फिर यह तय करने के लिए कि आपको जो भी आकृतियाँ बनाने की आवश्यकता है, उसे बनाने के लिए AbstractFactory का उपयोग करें ।


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

1

यदि आप ऐब्सट्रैक्ट फैक्ट्री पैटर्न के बारे में बात कर रहे हैं, तो निर्णय लेने का कार्य अक्सर फैक्ट्री में ही नहीं बल्कि एप्लिकेशन कोड में होता है। यह वह कोड है जो चुनता है कि कौन सी कंक्रीट फैक्ट्री ग्राहक कोड को तत्काल भेजती है और पास करती है जो कि कारखाने द्वारा उत्पादित वस्तुओं का उपयोग करेगी। जावा उदाहरण का अंत यहां देखें: https://en.wikipedia.org/wiki/Abstract_factory_pattern

निर्णय लेना जरूरी नहीं है कि ifबयान का अर्थ है। यह कॉन्फिगर फाइल से कंक्रीट फैक्ट्री प्रकार को पढ़ सकता है, इसे मैप स्ट्रक्चर से प्राप्त कर सकता है, आदि।



अगर मैं, फोन करने वाला, यह निर्णय ले रहा हूं कि कौन सा ठोस वर्ग तात्कालिक है, तो मैं एब्सट्रैक्ट फैक्ट्री से परेशान क्यों हूं?
रॉबर्ट हार्वे

कृपया "कॉलर" को परिभाषित करें। जैसा कि मैंने अपने उत्तर में वर्णन किया है, वैश्विक अनुप्रयोग कोड है और फिर एक कोड है जिसे एक कारखाने का उपयोग करके वस्तुओं को स्पॉन करने की आवश्यकता है। यद्यपि द्वितीय वास्तव में इन्स्तांत के लिए ठोस वर्ग से अनजान होने की जरूरत है, कुछ अन्य प्रासंगिक कोड है यह और नए इसे के बारे में पता करने के लिए ...
guillaume31

0

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

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


0

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


-2

यह सब निर्भर करता है कि आप इसे कैसे लागू करते हैं। आप std::mapफ़ंक्शन पॉइंटर्स को ऑब्जेक्ट्स बनाने के फ़ंक्शन के लिए उपयोग कर सकते हैं । तब खुले / करीब सिद्धांत का उल्लंघन नहीं किया जाता है। या स्विच / केस।

वैसे भी, यदि आप कारखाने के पैटर्न को पसंद नहीं करते हैं, तो आप हमेशा निर्भरता इंजेक्शन का उपयोग कर सकते हैं।


6
सशर्त की तुलना में स्विच / केस कैसे बेहतर है? कोड को डेटा के रूप में दर्शाने के लिए मैप / डिक्टेड / टेबल का उपयोग करना अच्छा होता है, अगर आपको वास्तव में अलग-अलग कार्यान्वयन की रजिस्ट्री की आवश्यकता होती है - जैसे कि कुछ DIOS कार्यान्वयन में। लेकिन अधिकांश कारखानों के लिए एक ही प्रकार के अलग-अलग कॉलबैक होना आवश्यक नहीं है! मुझे यह समझ में नहीं आता कि आप ऐसा क्यों सुझाव दे रहे हैं। इसके अलावा, कई DI कंटेनरों को फैक्ट्री ऑब्जेक्ट्स के संदर्भ में लागू किया जाता है, इसलिए कारखानों के बजाय DI का उपयोग करने का सुझाव थोड़ा गोलाकार लगता है।
अमोन

1
@ मैं अन्य प्रकार के DI का उपयोग करने के लिए था - कारखाने का नहीं।
B34овиЈ


1
कैसे अपने कारखाने का फैसला करने के लिए जो सूचक का उपयोग करने जा रहा है? आखिरकार आपको एक निर्णय लेना होगा।
whatsisname

@ArmonSafai ???
B19овиЈ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.