कई सॉफ्टवेयर डेवलपर्स खुले / बंद सिद्धांत का उल्लंघन क्यों करते हैं?


74

कई सॉफ्टवेयर डेवलपर्स खुले कार्यों को संशोधित करने जैसे कई कार्यों को संशोधित करके खुले / बंद सिद्धांत का उल्लंघन क्यों करते हैं जो उन्नयन के बाद आवेदन को तोड़ देगा?

यह सवाल रिएक्ट लाइब्रेरी में तेज और निरंतर संस्करणों के बाद मेरे सिर पर कूदता है ।

हर छोटी अवधि मैं वाक्यविन्यास, घटक नाम, ... आदि में कई बदलाव देखे जाते हैं

प्रतिक्रिया के आने वाले संस्करण में उदाहरण :

नई अवसाद चेतावनी

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

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


  • क्या इन परिवर्तनों को उस सिद्धांत का उल्लंघन माना जाता है?
  • रिएक्ट जैसी किसी चीज़ की शुरुआत करने वाले के रूप में , मैं इसे लाइब्रेरी में इन तेज़ बदलावों के साथ कैसे सीख सकता हूँ (यह इतना निराशाजनक है)?

6
यह स्पष्ट रूप से इसे देखने का एक उदाहरण है, और आपका दावा 'इतने सारे' असंतुलित है। Lucene और RichFaces परियोजनाएं कुख्यात उदाहरण हैं, और Windows COMM पोर्ट API, लेकिन मैं किसी भी अन्य व्यक्ति के बारे में नहीं सोच सकता। और क्या रिएक्ट वास्तव में एक 'बड़ा सॉफ्टवेयर डेवलपर' है?
user207421

62
किसी भी सिद्धांत की तरह, OCP का मूल्य है। लेकिन इसके लिए यह आवश्यक है कि डेवलपर्स के पास दूरदर्शिता हो। वास्तविक दुनिया में, लोग अक्सर अपने पहले डिजाइन को गलत पाते हैं। समय बीतने के साथ, कुछ अपनी पुरानी गलतियों के लिए अनुकूलता के लिए काम करना पसंद करते हैं, अन्य अंततः एक कॉम्पैक्ट और असभ्य कोडबेस होने के लिए उन्हें साफ करना पसंद करते हैं।
थियोडोरोस चटजिआनकिंस

1
जब पिछली बार आपने ऑब्जेक्ट-ओरिएंटेड भाषा देखी थी "जैसा कि मूल रूप से इरादा था"? मुख्य सिद्धांत एक मैसेजिंग सिस्टम था जिसका मतलब था कि सिस्टम का हर हिस्सा किसी के द्वारा भी असीम रूप से एक्स्टेंसिबल है। अब इसकी तुलना अपनी विशिष्ट OOP जैसी भाषा से करें - कितने आपको बाहर से मौजूदा पद्धति का विस्तार करने की अनुमति देते हैं? कितने इसे आसान बनाने के लिए उपयोगी है?
लुआण

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

4
क्योंकि बिल्कुल शून्य "सिद्धांत" और "डिजाइन पैटर्न" हैं जो वास्तविक जीवन में 100% समय का काम करते हैं।
मत्ती विर्ककुनेन

जवाबों:


148

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

जैसा कि Jörg W Mittag ने पहले ही अपनी टिप्पणियों में उल्लेख किया है, सिद्धांत यह नहीं कहता है कि "आप किसी घटक के व्यवहार को संशोधित नहीं कर सकते हैं" - यह कहता है, किसी को पुन: उपयोग किए जा रहे मधुमक्खी (या विस्तारित) के लिए घटकों को डिजाइन करने का प्रयास करना चाहिए संशोधन की आवश्यकता के बिना कई मायनों में । यह सही "एक्सटेंशन पॉइंट" प्रदान करके किया जा सकता है, या, जैसा कि @AntP द्वारा उल्लेख किया गया है, "एक क्लास / फ़ंक्शन संरचना को उस बिंदु पर विघटित करके जहां हर प्राकृतिक एक्सटेंशन बिंदु डिफ़ॉल्ट रूप से है।" OCP के बाद IMHO के पास "पीछे की संगतता के लिए पुराने संस्करण को अपरिवर्तित रखने" के साथ कुछ भी सामान्य नहीं है ! या, नीचे @ DerekElkin की टिप्पणी उद्धृत:

OCP मॉड्यूल को लिखने के तरीके के बारे में सलाह देता है [...], परिवर्तन प्रबंधन प्रक्रिया को लागू करने के बारे में नहीं जो मॉड्यूल को कभी भी बदलने की अनुमति नहीं देता है।

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


14
IMO OCP का "उल्लंघन" करने का सबसे बड़ा कारण यह है कि इसे ठीक से पूरा करने के लिए बहुत प्रयास करना पड़ता है। एरिक लिपर्ट के पास एक उत्कृष्ट ब्लॉग पोस्ट है , जिसमें बहुत से .NET फ्रेमवर्क वर्ग OCP का उल्लंघन करते हैं।
बीजे मायर्स

2
@BJMyers: लिंक के लिए धन्यवाद। जॉन स्कीट के पास OCP के बारे में एक उत्कृष्ट पोस्ट है जो संरक्षित भिन्नता के विचार के समान है।
डॉक ब्राउन

8
इस! OCP का कहना है कि आपको ऐसा कोड लिखना चाहिए जिसे बिना छुए बदला जा सके! क्यों? इसलिए आपको केवल एक बार परीक्षण, समीक्षा और संकलन करना है। नया व्यवहार नए कोड से आना चाहिए। पुराने सिद्ध कोड से पंगा लेकर नहीं। रिफैक्टरिंग के बारे में क्या? अच्छी तरह से refactoring OCP का स्पष्ट उल्लंघन है! यही कारण है कि कोड सोच लिखना एक पाप है यदि आप अपनी मान्यताओं को बदलते हैं तो आप इसे फिर से प्रतिबिंबित करेंगे। नहीं! प्रत्येक धारणा को अपने छोटे बॉक्स में रखें। जब यह गलत हो तो बॉक्स को ठीक न करें। एक नया लिखो। क्यों? क्योंकि आपको पुराने वाले पर वापस जाने की आवश्यकता हो सकती है। जब आप करते हैं, यह अच्छा होगा अगर यह अभी भी काम करता है।
candied_orange

7
@CandiedOrange: आपकी टिप्पणी के लिए धन्यवाद। जैसा कि आप इसका वर्णन करते हैं, मैं उसके विपरीत और ओसीपी को नहीं देखता हूं। OCP का अनुसरण करने वाले घटकों को लिखने के लिए अक्सर कई रीफैक्टरिंग चक्रों की आवश्यकता होती है। लक्ष्य एक घटक होना चाहिए जिसे आवश्यकताओं के एक पूरे "परिवार" को हल करने के लिए संशोधनों की आवश्यकता नहीं है। फिर भी, किसी को "बस के मामले में" एक घटक के लिए मनमाने ढंग से विस्तार बिंदुओं को नहीं जोड़ना चाहिए, जो अतिव्यापीता को भी आसानी से ले जाता है। बहुत सारे मामलों में रिफ्लैक्टरिंग की संभावना का पालन करना इसका बेहतर विकल्प हो सकता है।
डॉक ब्राउन

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

67

खुले / बंद सिद्धांत के लाभ हैं, लेकिन इसमें कुछ गंभीर कमियां भी हैं।

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

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

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

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

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

जाहिर तौर पर प्रतिक्रिया के डेवलपर्स ने महसूस किया है कि खुले / बंद सिद्धांत का सख्ती से पालन करने के लिए जटिलता और कोड-ब्लोट में लागत के लायक नहीं था।

खोलने / बंद करने के लिए व्यावहारिक विकल्प को नियंत्रित किया जाता है। किसी एकल रिलीज में पीछे की ओर की संगतता को तोड़ने के बजाय, पुराने घटकों को एक रिलीज चक्र के लिए चारों ओर रखा जाता है, लेकिन क्लाइंट को संकलक चेतावनी के माध्यम से सूचित किया जाता है कि पुराने दृष्टिकोण को बाद के रिलीज में हटा दिया जाएगा। इससे ग्राहकों को कोड को संशोधित करने का समय मिल जाता है। यह इस मामले में प्रतिक्रिया का दृष्टिकोण प्रतीत होता है।

(सिद्धांत की मेरी व्याख्या रॉबर्ट सी। मार्टिन द्वारा ओपन-क्लोज्ड सिद्धांत पर आधारित है )


37
"सिद्धांत मूल रूप से कहता है कि आप एक घटक के व्यवहार को संशोधित नहीं कर सकते। इसके बजाय आपको वांछित व्यवहार के साथ घटक का एक नया संस्करण प्रदान करना होगा, और पुराने संस्करण को पीछे की संगतता के लिए अपरिवर्तित रखना होगा।" - मैं इससे असहमत हूं। सिद्धांत कहता है कि आपको घटकों को इस तरह से डिज़ाइन करना चाहिए कि इसके व्यवहार को बदलना आवश्यक नहीं होना चाहिए क्योंकि आप इसे अपनी इच्छानुसार करने के लिए बढ़ा सकते हैं। समस्या यह है कि हमें यह पता नहीं चला है कि ऐसा कैसे किया जा सकता है, विशेषकर उन भाषाओं के साथ जो वर्तमान में व्यापक प्रसार वाले हैं। अभिव्यक्ति की समस्या का एक हिस्सा है ...
Jörg W Mittag

8
… उदाहरण के लिए। एक्सप्रेशन के लिए न तो जावा और न ही ither का समाधान है। हास्केल और स्काला करते हैं, लेकिन उनका यूजरबेस बहुत छोटा है।
जॉर्ग डब्ल्यू मित्तग

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

1
... भाषा भी इस "कठिन" संस्करण को हल कर सकती है। उदाहरण के लिए, वाडलर ने मूल रूप से न केवल मॉड्यूलर एक्सटेंशन के बारे में, बल्कि सांख्यिकीय रूप से सुरक्षित मॉड्यूलर एक्सटेंशन के लिए अभिव्यक्ति की समस्या को प्रतिपादित किया । आम लिस्प मल्टीमिथोड हालांकि सांख्यिकीय रूप से सुरक्षित नहीं हैं , वे केवल गतिशील रूप से सुरक्षित हैं। ओडस्की ने तब इसे और भी मजबूत किया, यह कहकर कि यह सांख्यिकीय रूप से सुरक्षित होना चाहिए, अर्थात पूरे कार्यक्रम को देखने के बिना सुरक्षा को सांख्यिकीय रूप से जाँच योग्य होना चाहिए, केवल विस्तार मॉड्यूल को देखकर। यह वास्तव में हास्केल प्रकार की कक्षाओं के साथ नहीं किया जा सकता है, लेकिन यह स्काला के साथ किया जा सकता है। और…
डब्ल्यू पर Jörg W Mittag

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

20

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

कहानी के दूसरे पक्ष को स्वर्ण हथकड़ी के रूप में जाना जाता है। गोल्डन हैंडकफ्स आपको तब मिलते हैं जब आप खुद को खुले / बंद सिद्धांत पर बहुत अधिक गुलाम करते हैं। गोल्डन हैंडकफ्स तब होते हैं जब आपका उत्पाद जो कभी पीछे की ओर नहीं जाता है संगतता नहीं बढ़ सकता है क्योंकि बहुत सारी पिछली गलतियां की गई हैं।

इसका एक प्रसिद्ध उदाहरण विंडोज 95 मेमोरी मैनेजर में पाया जाता है। विंडोज 95 के लिए विपणन के भाग के रूप में, यह कहा गया था कि सभी विंडोज 3.1 अनुप्रयोग विंडोज 95 में काम करेंगे। माइक्रोसॉफ्ट ने वास्तव में विंडोज 95 में उन्हें परीक्षण करने के लिए हजारों कार्यक्रमों के लिए लाइसेंस प्राप्त किया। समस्या मामलों में से एक सिम सिटी थी। सिम सिटी में वास्तव में एक बग था, जिसके कारण यह असंबद्ध स्मृति में लिखा गया था। विंडोज 3.1 में, "उचित" मेमोरी मैनेजर के बिना, यह एक मामूली अशुद्ध पेस था। हालाँकि, विंडोज 95 में, मेमोरी मैनेजर इसे पकड़ लेता है और एक विभाजन दोष का कारण बनता है। समाधान? विंडोज 95 में, यदि आपका एप्लिकेशन नाम है simcity.exe, तो ओएस वास्तव में विभाजन की गलती को रोकने के लिए मेमोरी मैनेजर की बाधाओं को आराम देगा!

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

अधिकांश सॉफ्टवेयर आज, विशेष रूप से खुले स्रोत, खुले / बंद सिद्धांत के एक सामान्य आराम संस्करण का अनुसरण करते हैं। मामूली रिलीज के लिए खुले तौर पर / बंद का पालन करना बहुत आम है, लेकिन प्रमुख रिलीज के लिए छोड़ दिया गया। उदाहरण के लिए, पायथन 2.7 में पायथन 2.0 और 2.1 दिनों के कई "बुरे विकल्प" शामिल हैं, लेकिन पायथन 3.0 ने सभी को बहा दिया। (इसके अलावा, विंडोज 95 कोडबेस से विंडोज एनटी कोडबेस में शिफ्ट होने पर, जब उन्होंने विंडोज 2000 जारी किया, तो सभी तरह की चीजें टूट गईं, लेकिन इसका मतलब यह था कि हमें व्यवहार को तय करने के लिए एप्लिकेशन मैनेजर की जांच करने वाले मेमोरी मैनेजर से कभी नहीं निपटना होगा!


यह SimCity के बारे में एक बहुत अच्छी कहानी है। क्या आपके पास कोई ज़रिया है?
बीजे मायर्स

5
@BJMyers यह एक पुरानी कहानी है, जोएल स्पोलेकी ने इस लेख के अंत के पास इसका उल्लेख किया है । मैंने मूल रूप से वर्षों पहले वीडियो गेम विकसित करने पर एक किताब के हिस्से के रूप में इसे पढ़ा।
कॉर्ट अमोन

1
@BJMyers: मुझे पूरा यकीन है कि दर्जनों लोकप्रिय अनुप्रयोगों के लिए उनके पास समान संगतता "हैक" थी।
डॉक ब्राउन

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

2
95-> NT संक्रमण में भी बहुत कम चीजें टूटीं। विंडोज के लिए मूल SimCity अभी भी विंडोज 10 (32-बिट) पर बहुत अच्छा काम करता है। यहां तक ​​कि डॉस गेम्स अभी भी पूरी तरह से ठीक काम करते हैं, बशर्ते आप ध्वनि को अक्षम करें या ऑडियो को ठीक से संभालने के लिए कंसोल सबसिस्टम की अनुमति देने के लिए VDMSound जैसी किसी चीज़ का उपयोग करें। Microsoft बैकवर्ड संगतता को बहुत गंभीरता से लेता है , और वे कोई भी "वर्चुअल मशीन में नहीं डालते हैं" शॉर्टकट या तो ले रहे हैं। इसे कभी-कभी वर्कअराउंड की आवश्यकता होती है, लेकिन यह अभी भी बहुत प्रभावशाली है, विशेष रूप से सापेक्ष शब्दों में।
लुआण

11

डॉक्टर ब्राउन का उत्तर सटीक है, अन्य उत्तर ओपन बंद सिद्धांत की गलतफहमी को दर्शाते हैं।

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

वास्तव में, यह स्रोत कोड के बारे में बिल्कुल नहीं है। OCP का एक अधिक सार और प्रासंगिक कथन है: "एक घटक को अपनी अमूर्त सीमाओं के उल्लंघन की आवश्यकता के बिना विस्तार की अनुमति देनी चाहिए"। मैं आगे जाऊंगा और एक और आधुनिक प्रतिपादन कहूंगा: "एक घटक को अपनी अमूर्त सीमाओं को लागू करना चाहिए लेकिन विस्तार के लिए अनुमति देना चाहिए "। यहां तक ​​कि बॉब मार्टिन द्वारा ओसीपी पर लेख में, जबकि वह "" संशोधन के लिए बंद "" स्रोत कोड के रूप में "का वर्णन करता है", वह बाद में इनकैप्सुलेशन के बारे में बात करना शुरू कर देता है जिसका संशोधित स्रोत कोड से कोई लेना-देना नहीं है और अमूर्त करने के लिए सब कुछ है। सीमाओं।

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

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

तो आपके सवालों के जवाब देने के लिए: नहीं, ये OCP के उल्लंघन नहीं हैं। लेखक द्वारा कोई भी परिवर्तन OCP का उल्लंघन नहीं हो सकता है क्योंकि OCP परिवर्तनों का आनुपातिक नहीं है। हालाँकि, परिवर्तन OCP के उल्लंघन पैदा कर सकते हैं , और वे कोडबेस के पूर्व संस्करणों में OCP की विफलताओं से प्रेरित हो सकते हैं। OCP कोड के एक विशेष टुकड़े की एक संपत्ति है, न कि किसी कोडबेस का विकासवादी इतिहास।

इसके विपरीत, बैकवर्ड संगतता कोड के परिवर्तन की एक संपत्ति है । यह कहने का कोई मतलब नहीं है कि कुछ कोड कोड है या पीछे की ओर संगत नहीं है। यह केवल कुछ पुराने कोड के संबंध में कुछ कोड के पीछे की संगतता के बारे में बात करने के लिए समझ में आता है । इसलिए, कुछ कोड के पहले कट के पीछे संगत होने या न होने के बारे में बात करने का कोई मतलब नहीं है। कोड की पहली कटौती OCP को संतुष्ट करने या विफल करने के लिए हो सकती है, और सामान्य तौर पर हम यह निर्धारित कर सकते हैं कि क्या कुछ कोड OCP को कोड के किसी भी ऐतिहासिक संस्करण को संदर्भित किए बिना संतुष्ट करता है या नहीं।

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


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

1
@JacquesB लोग और यहां तक ​​कि कोड परिवर्तन OCP का उल्लंघन नहीं करते हैं, घटक (यानी कोड के वास्तविक टुकड़े) करते हैं। (और, पूरी तरह से स्पष्ट होने का मतलब है कि घटक OCP के लिए स्वयं ही रहने में विफल रहता है, यह नहीं कि यह किसी अन्य घटक के OCP का उल्लंघन करता है।) मेरे उत्तर का पूरा बिंदु यह है कि OCP कोड परिवर्तन के बारे में बात नहीं कर रहा है। , तोड़ना या अन्यथा। एक घटक या तो विस्तार के लिए खुला है और संशोधन के लिए बंद है, या यह नहीं है, जैसे एक विधि हो सकती है privateया नहीं। यदि कोई लेखक बाद में एक privateविधि बनाता है public, तो इसका मतलब यह नहीं है कि उन्होंने अभिगम नियंत्रण का उल्लंघन किया है, (1/2)
डेरेक एल्किंस

2
... और न ही इसका मतलब यह है कि विधि वास्तव में privateपहले नहीं थी । "प्रकाशित घटक को हटाना स्पष्ट रूप से एक ब्रेकिंग परिवर्तन है," एक गैर अनुक्रमिक है। या तो नए संस्करण के घटक ओसीपी को संतुष्ट करते हैं या वे नहीं करते हैं, आपको इसे निर्धारित करने के लिए कोडबेस के इतिहास की आवश्यकता नहीं है। आपके तर्क से, मैं कभी भी ऐसा कोड नहीं लिख सका जो OCP को संतुष्ट करता हो। आप कोड की संपत्ति, OCP के साथ कोड परिवर्तन की संपत्ति, बैकवर्ड संगतता का सामना कर रहे हैं। आपकी टिप्पणी के बारे में उतना ही समझ में आता है जितना कहना है कि क्विकॉर्ट पीछे की ओर संगत नहीं है। (2/2)
डेरेक एल्किंस

3
@JacquesB सबसे पहले, ध्यान दें कि यह OCP के अनुरूप एक मॉड्यूल के बारे में बात कर रहा है । ओसीपी कैसे पर सलाह है लिखना एक मॉड्यूल ताकि बाधा दी है कि स्रोत कोड नहीं बदला जा सकता, फिर भी मॉड्यूल बढ़ाया जा सकता है। पहले पेपर में वह ऐसे मॉड्यूल्स के डिजाइन के बारे में बात करता है जो कभी नहीं बदलते हैं, न कि एक बदलाव प्रबंधन प्रक्रिया को लागू करने के बारे में जो कभी भी मॉड्यूल को बदलने की अनुमति नहीं देता है। अपने उत्तर को संपादित करने का उल्लेख करते हुए, आप मॉड्यूल के कोड को संशोधित करके "ओसीपी को तोड़ नहीं" करते हैं। इसके बजाय, यदि "विस्तार" से आपको स्रोत कोड को संशोधित करने की आवश्यकता होती है , (1/3)
डेरेक एल्किंस

2
"OCP कोड के एक विशेष टुकड़े की संपत्ति है, न कि किसी कोडबेस का विकासवादी इतिहास।" - अति उत्कृष्ट!
डॉक्टर ब्राउन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.