ओपन / बंद सिद्धांत को स्पष्ट करें


25

जैसा कि मैंने समझाया है, खुले / बंद सिद्धांत में कहा गया है कि एक बार लिखित कोड को संशोधित नहीं किया जाना चाहिए (बग फिक्स से अलग)। लेकिन अगर मेरे व्यावसायिक नियम बदलते हैं तो क्या मुझे उन परिवर्तनों को लागू करने वाले कोड को संशोधित नहीं करना चाहिए? मुझे संदेह है कि मैं इस बारे में कुछ नहीं समझ रहा हूं कि सिद्धांत कैसे है क्योंकि यह मेरे लिए समझ में नहीं आता है।

जवाबों:


22

यह समझाने के लिए ठोस सिद्धांतों में शायद सबसे कठिन है। मुझे कोशिश करने दो। कल्पना कीजिए कि आपने एक इनवॉइस क्लास लिखी है जो पूरी तरह से काम करती है और इसमें कोई बग नहीं है। यह एक चालान का एक पीडीएफ बनाता है।

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

पुराना कोड जो पुराने इनवॉइस का उपयोग कर रहा था वह किसी भी तरह से टूटा हुआ या वास्तव में प्रभावित नहीं हुआ है। नया कोड HTMLInvoice का उपयोग कर सकता है। (यदि आप Liskov सबस्टिबिलिटी, सॉलिड के L भी करते हैं , तो आप मौजूदा कोड के लिए HTMLInvoice इंस्टेंस दे सकते हैं, जो इनवॉइस इंस्टैंस की अपेक्षा कर रहा है।) हर कोई खुशी के साथ कभी भी रहता है।

चालान संशोधन के लिए बंद है, विस्तार के लिए खुला है। और आपको इनवॉइस को काम करने के लिए अग्रिम में ठीक से लिखना होगा, btw।


1
यदि व्यावसायिक नियम बदलते हैं तो बिना किसी कीड़े के पूरी तरह से काम करने की कोई धारणा नहीं है, इसलिए खुला / करीबी सिद्धांत लागू नहीं होता है?
जेएफओ

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

1
@Jeff OI बग को ठीक करने के बीच अंतर करता है (जहां कोड मूल आवश्यकता को पूरा नहीं करता था और कोई भी इसे वैसा ही नहीं चाहता है) और आवश्यकताओं को बदल रहा है। अगर मुझे PDF की आवश्यकता है और कोड PDF बनाता है, तो कोई बग नहीं है, भले ही मुझे अब HTML चाहिए (और आमतौर पर लोग HTML चाहते हैं, इसके बजाय नहीं।)
केट ग्रेगरी

2
@Winston - इसका मतलब है जब मैंने कहा था कि आपको इनवॉयस को ठीक से लिखना होगा। आदर्श रूप से पहले से ही एक बहुत ही सारगर्भित चालान था और आपको उम्मीद है कि PDFInvoice विरासत में मिला है। यदि नहीं, तो आपको भविष्य में इसे न तोड़ने के लिए खुद को स्थापित करने के लिए एक बार नियम को तोड़ना होगा। किसी भी तरह से, भविष्य के परिवर्तनों की भविष्यवाणी करना इस सब का एक बड़ा हिस्सा है - और यह नुस्खा का "हाथी को पकड़ और काट" ​​है।
केट ग्रेगोरी

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

13

क्या आपने ObjectMentor पर चाचा बॉब के दोस्तों द्वारा ओपन-क्लोज्ड सिद्धांत लेख पढ़ा है? मुझे लगता है कि यह बेहतर स्पष्टीकरणों में से एक है।

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

जैसा कि इवर जैकबसन ने कहा था: “उनके जीवन चक्र के दौरान सभी प्रणालियाँ बदल जाती हैं। यह तब ध्यान में रखना चाहिए जब विकासशील प्रणालियाँ पहले संस्करण की तुलना में अधिक समय तक चलने की उम्मीद करती हैं। ”हम ऐसे डिजाइन कैसे बना सकते हैं जो परिवर्तन के चेहरे पर स्थिर हों और जो पहले संस्करण की तुलना में अधिक समय तक चलेंगे? बर्ट्रेंड मेयर ने हमें बहुत पहले 1988 तक मार्गदर्शन दिया जब उन्होंने अब तक के प्रसिद्ध खुले-बंद सिद्धांत को गढ़ा। उसे विमुग्ध करने के लिए:

सॉफ़्टवेयर ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) शोषण के लिए खुला होना चाहिए, विवरण के लिए बंद किया गया।

जब एक कार्यक्रम के लिए एक एकल परिवर्तन निर्भर मॉड्यूल के लिए परिवर्तनों के एक झरना में परिणाम होता है, तो यह कार्यक्रम अवांछनीय विशेषताओं को प्रदर्शित करता है जिसे हम "खराब" डिजाइन के साथ जोड़कर आए हैं। कार्यक्रम नाजुक, कठोर, अप्रत्याशित और अप्राप्य हो जाता है। खुले-बंद सिद्धांत इस पर बहुत ही सीधे तरीके से हमला करते हैं। यह कहता है कि आपको ऐसे मॉड्यूल डिजाइन करने चाहिए जो कभी नहीं बदलते । जब आवश्यकताएं बदलती हैं, तो आप नए कोड को जोड़कर ऐसे मॉड्यूल के व्यवहार का विस्तार करते हैं, न कि पुराने कोड को बदलकर जो पहले से ही काम करता है।

विवरण

खुले-बंद सिद्धांत के अनुरूप मॉड्यूल में दो प्राथमिक गुण होते हैं।

  1. वे "एक्सटेंशन के लिए ओपन" हैं।
    इसका मतलब है कि मॉड्यूल के व्यवहार को बढ़ाया जा सकता है। कि हम मॉड्यूल को नए और अलग-अलग तरीकों से व्यवहार में परिवर्तन कर सकते हैं जैसे कि आवेदन में परिवर्तन, या नए अनुप्रयोगों की जरूरतों को पूरा करने के लिए।
  2. वे "संशोधन के लिए बंद हैं"।
    इस तरह के एक मॉड्यूल का स्रोत कोड इनवॉयलेट है। किसी को भी स्रोत कोड परिवर्तन करने की अनुमति नहीं है।

ऐसा लगता है कि ये दोनों विशेषताएँ एक-दूसरे के साथ हैं। किसी मॉड्यूल के व्यवहार का विस्तार करने का सामान्य तरीका उस मॉड्यूल में परिवर्तन करना है। एक मॉड्यूल जिसे बदला नहीं जा सकता है उसे सामान्य रूप से एक निश्चित व्यवहार माना जाता है। इन दो विरोधी विशेषताओं को कैसे हल किया जा सकता है?

अमूर्त कुंजी है ...


3
यह अमूर्त व्याख्या करने वाला एक अच्छा लेख है। हालांकि, माना जाने वाला एक मूलभूत बिंदु है, और यह एक अच्छा सार डिजाइन था जो पहले स्थान पर रखा गया था? कई दुकानों में बहुत सी विरासत कोड हैं जिन्हें बदलने का एकमात्र तरीका "संशोधन" है, न कि "विस्तार"। यदि यह मामला है, तो किसी को शायद इसे बदलने के लिए काम करना चाहिए, लेकिन जब तक यह नहीं होता है, तब तक आप कोड को संशोधित कर रहे हैं।
माइकल के

@ क्रिस, कूल - मैं भी अंकल बॉब द्वारा "क्लीन कोड" पुस्तक की सिफारिश करता हूं अगर आपको इस तरह की बात पसंद है।
मार्टिज़न वेरबर्ग

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

लेख बहुत बारीकी से अमूर्तता के महत्व को दर्शाता है। लेकिन मैं अमूर्तता के बीच के संबंध को नहीं समझ रहा हूं और उन्हें लिखने के बाद कभी भी मॉड्यूल को संशोधित करने की कोशिश नहीं कर रहा हूं। अमूर्तता का अर्थ है कि मैं मॉड्यूल Y में संशोधन किए बिना मॉड्यूल X को संशोधित कर सकता हूं। लेकिन ऐसा करने की बात नहीं है, इसलिए यदि मुझे आवश्यकता है तो मैं मॉड्यूल X या मॉड्यूल Y को संशोधित कर सकता हूं?
विंस्टन एवर्ट

1
वाह। कोड है? मैं कभी भी अंकल बॉब का बहुत बड़ा प्रशंसक नहीं रहा। यह प्रिंसिपल पांडित्यपूर्ण है, बेहद गैर-व्यावहारिक है और इसका वास्तविकता से सीमित संबंध है।
user949300

12

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

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


2
हां, क्योंकि व्यवहार में, एक ऐसा वर्ग बनाना संभव नहीं है, जिसे सभी संभव वायदा के अनुरूप बढ़ाया जा सकता है, जब तक कि आप सभी तरीकों को संरक्षित नहीं करते (जो बेकार है और YAGNI सिद्धांत का भी उल्लंघन करता है, जो कि O / C की तुलना में बहुत अधिक महत्वहीन है) Dito)।
मार्टिन विकमन

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

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

@Giorgio ज़रूर, नए क्षेत्रों या तरीकों को जोड़ने से मैं ज्यादातर मामलों में क्या सिफारिश करूंगा। लेकिन यह विस्तार नहीं है , यह "संशोधन" है; OCP का पूरा बिंदु यह है कि "एक्सटेंशन के लिए खुला" होने के दौरान कोड "संशोधन के लिए बंद होना चाहिए" (यानी, पूर्व-मौजूदा स्रोत फ़ाइल में कोई परिवर्तन नहीं); और कार्यान्वयन विरासत के माध्यम से OCP में विस्तार हासिल किया जाता है।
रोजेरियो

@ रोजेरियो: आप वर्ग स्तर पर विस्तार और संशोधन के बीच की सीमा को क्यों परिभाषित करते हैं? क्या इसकी कोई खास वजह है? मैं इसे विधि के स्तर पर सेट करूंगा: एक विधि को बदलने से आपके एप्लिकेशन का व्यवहार बदल जाता है, एक (सार्वजनिक) विधि जोड़ने से इसका इंटरफ़ेस विस्तारित होता है।
जियोर्जियो

6

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

मुझे इस तथ्य के बारे में अपना सिर प्राप्त करना बहुत मुश्किल है कि अमूर्तता महत्वपूर्ण है। क्या होगा अगर अमूर्त मूल रूप से गलत था? क्या होगा यदि व्यवसाय फ़ंक्शन में काफी बदलाव आया है?

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

अपने कोड का अच्छा परीक्षण कवरेज होने से आपके कोड आधार को रीफ्रैक्टिंग करना चाहिए। इसका मतलब है कि सामान गलत होना ठीक है - आपके परीक्षण आपको बेहतर डिजाइन के लिए मार्गदर्शन करने में मदद करेंगे।

यह कहते हुए कि, यदि कोई परीक्षण नहीं है, तो यह सिद्धांत ध्वनि है।

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