लेख

सोलिड तत्वानुसार उघडे / बंद

सॉफ्टवेअर घटक (वर्ग, विभाग, कार्ये इ.) विस्तारासाठी खुले असले पाहिजेत, परंतु संपादनासाठी बंद.

सॉफ्टवेअर डिझाईन करणे: मॉड्यूल्स, वर्ग आणि कार्ये अशा प्रकारे की जेव्हा नवीन कार्यक्षमता आवश्यक असेल तेव्हा आम्ही विद्यमान कोडमध्ये बदल करू नये परंतु विद्यमान कोडद्वारे वापरला जाणारा नवीन कोड लिहू नये. हे कदाचित विचित्र वाटेल, विशेषत: जावा, सी, सी ++ किंवा सी # सारख्या भाषांमध्ये जेथे ते केवळ स्त्रोत कोडवरच नाही तर बायनरीवर देखील लागू होते. आम्हाला विद्यमान बायनरी, एक्झिक्युटेबल किंवा डीएलएलचे पुनर्वितरण आवश्यक नसते अशा प्रकारे नवीन वैशिष्ट्ये तयार करू इच्छित आहोत.
सोलिड संदर्भात ओसीपी

 

पूरक एसआरपी आणि ओसीपी

आम्ही आधीपासूनच एकल जबाबदारीची एसआरपी तत्व पाहिली आहे ज्यामध्ये असे नमूद केले आहे की मॉड्यूलमध्ये बदलण्याचे फक्त एकच कारण असावे. ओसीपी आणि एसआरपी तत्त्वे पूरक आहेत. एसआरपी तत्त्वाचे पालन केले गेलेले कोड ओसीपी तत्त्वांचा देखील आदर करेल. जेव्हा आमच्याकडे बदल करण्याचे फक्त एक कारण आहे असे कोड असेल तेव्हा नवीन वैशिष्ट्य सादर केल्याने त्या बदलाचे दुय्यम कारण तयार होईल. तर एसआरपी आणि ओसीपी दोघांचा भंग होईल. त्याचप्रमाणे, जर आमच्याकडे कोड आहे ज्यामध्ये केवळ त्याचे मुख्य कार्य बदलते तेव्हाच बदलले पाहिजे आणि नवीन कार्यक्षमता जोडली जाते तेव्हा ती बदलली पाहिजे, अशा प्रकारे ओसीपीचा आदर करते, तर मुख्यत: एसआरपीचा देखील आदर करेल.
याचा अर्थ असा नाही की एसआरपी नेहमी ओसीपी किंवा त्याउलट होतो, परंतु बहुतेक प्रकरणांमध्ये जर त्यापैकी एखादा भेटला तर दुसर्‍यापर्यंत पोहोचणे अगदी सोपे आहे.

 

ओसीपी तत्त्वाचे उल्लंघन केल्याचे उदाहरण

पूर्णपणे तांत्रिक दृष्टीकोनातून, मुक्त / बंद तत्त्व अगदी सोपी आहे. खालील वर्गांप्रमाणेच दोन वर्गांमधील एक साधा संबंध ओसीपी तत्त्वाचे उल्लंघन करतो.

युजर क्लास थेट लॉजिक क्लास वापरतो. आम्हाला सध्याचा आणि नवीन दोन्ही वापरण्याची परवानगी देणार्‍या मार्गाने दुसरा लॉजिक क्लास लागू करण्याची आवश्यकता असल्यास, विद्यमान लॉजिक वर्ग बदलण्याची आवश्यकता आहे. युजर लॉजिकच्या अंमलबजावणीशी थेट जोडला गेला आहे, सध्याच्या गोष्टीवर परिणाम केल्याशिवाय आम्हाला नवीन लॉजिक प्रदान करण्याचा कोणताही मार्ग नाही. आणि जेव्हा आपण स्टॅटिकली टाइप केलेल्या भाषांबद्दल बोलू, तेव्हा वापरकर्त्याच्या वर्गालाही बदल आवश्यक असतात. जर आपण कंपाईल केलेल्या भाषांबद्दल बोललो तर नक्कीच वापरकर्ता एक्झिक्युटेबल आणि लॉजिक एक्झिक्युटेबल किंवा डायनॅमिक लायब्ररी आवश्यक असेल तेव्हा टाळण्यासाठी श्रेयस्कर रीकंपिलेशन आणि वितरण आवश्यक असेल.

मागील योजनेच्या संदर्भात, आम्ही असे अनुमान काढू शकतो की कोणताही वर्ग ज्याने थेट दुसरा वर्ग वापरला असेल, त्याला मुक्त / बंद तत्त्वाचे उल्लंघन होऊ शकते. 
समजा, आमच्या अर्जाद्वारे आम्ही डाउनलोड केलेल्या फाईलच्या "टक्केवारीत" प्रगती करण्यास सक्षम असा एखादा वर्ग लिहायचा आहे. आमच्याकडे प्रोग्रेस आणि फाईल असे दोन मुख्य वर्ग असतील आणि आम्हाला वाटते की आम्ही त्यांचा वापर खालीलप्रमाणे करू:

 

फंक्शन टेस्टआयटीकेनगेटटप्रोग्रेसऑफॅफिलएसेपरेंट () {
     $ फाईल = नवीन फाईल ();
     $ फाईल-> लांबी = 200;
     $ फाईल-> प्रेषित = 100;
     $ प्रगती = नवीन प्रगती (फाइल);
     $ हे-> assertEquals (50, $ प्रगती-> getAsPercent ());
}

या कोडमध्ये आम्ही प्रोग्रेसिझ यूझर आहोत. आम्हाला वास्तविक फाईल आकाराकडे दुर्लक्ष करून टक्केवारीप्रमाणे मूल्य मिळवायचे आहे. आम्ही माहितीचा स्रोत म्हणून फाईल वापरतो. फाईलची लांबी बाइटमध्ये असते आणि फील्डला सेंड म्हणतात जे डाउनलोडरला पाठविलेल्या डेटाचे प्रमाण दर्शवते. अनुप्रयोगात ही मूल्ये कशी अद्ययावत केली जातात याची आम्हाला काळजी नाही. आम्ही असे मानू शकतो की असे काही जादूचे तर्क आहे जे आपल्यासाठी हे करते, म्हणून परीक्षेमध्ये आम्ही त्यांना स्पष्टपणे सेट करू शकतो.

 

वर्ग फाइल {
     सार्वजनिक-लांबी;
     सार्वजनिक-पाठविले;
}

 

फाईल क्लास ही दोन फील्ड्स असलेली एक सोपी डेटा ऑब्जेक्ट आहे. अर्थात यात अन्य माहिती आणि वर्तन देखील असले पाहिजे जसे की फाइलनाव, पथ, संबंधित पथ, सद्य निर्देशिका, प्रकार, परवानग्या आणि असेच.

 

वर्ग प्रगती {

     खाजगी $ फाईल

     फंक्शन __ कॉन्स्ट्रक्ट (फाइल $ फाईल) {
          $ या-> फाईल = $ फाईल;
     }

     फंक्शन getAsPercent () {
          परत $ या-> फाइल-> * 100 / / या-> फाइल-> लांबी पाठविली;
     }

}

प्रगती म्हणजे एक वर्ग आहे जो त्याच्या कन्स्ट्रक्टरमध्ये फाईल स्वीकारतो. स्पष्टतेसाठी आम्ही कन्स्ट्रक्टर पॅरामीटर्समध्ये व्हेरिएबलचा प्रकार निर्दिष्ट केला आहे. प्रोग्रेस, गेटएस्पर्स () वर एक एकच उपयुक्त पद्धत आहे जी फाइलमधून पाठविलेली मूल्ये आणि लांबी घेईल आणि त्या टक्केवारीत रुपांतरित करेल. सोपे आणि ते कार्य करते.

हा कोड योग्य दिसत आहे, तथापि तो मुक्त / बंद तत्त्वाचे उल्लंघन करतो.

पण का?

आणि कसे?

 

गरजा बदलण्याचा प्रयत्न करूया

कालांतराने विकसित होणार्‍या प्रत्येक अनुप्रयोगास नवीन वैशिष्ट्यांची आवश्यकता असेल. आमच्या अनुप्रयोगासाठी एक नवीन वैशिष्ट्य म्हणजे फक्त फायली डाउनलोड करण्याऐवजी संगीत प्रवाहाची परवानगी देणे. फाईलची लांबी बाइटमध्ये दर्शविली जाते, सेकंदात संगीताचा कालावधी. आम्हाला आमच्या श्रोत्यांना प्रगती बार ऑफर करायचा आहे, परंतु आम्ही वर लिखित वर्गाचा पुन्हा वापर करू शकतो?

नाही आम्ही करू शकत नाही. आमची प्रगती फाईलला बांधील आहे. हे केवळ फाईल माहिती व्यवस्थापित करू शकते, जरी ती संगीत सामग्रीवर देखील लागू केली जाऊ शकते. परंतु आम्हाला ते सुधारित करायचे असल्यास, आम्हाला प्रोग्रेसला संगीत आणि फायली माहित करून घ्याव्या लागतील. आमच्या डिझाइनने ओसीपीचे पालन केले असल्यास आम्हाला फाईल किंवा प्रगती स्पर्श करण्याची गरज नाही. आम्ही फक्त विद्यमान प्रगतीचा पुनर्वापर करु आणि संगीतावर लागू करु शकू.

 

इनोव्हेशन वृत्तपत्र
नवोपक्रमावरील सर्वात महत्त्वाच्या बातम्या चुकवू नका. त्यांना ईमेलद्वारे प्राप्त करण्यासाठी साइन अप करा.

संभाव्य समाधान

डायनॅमिकली टाइप केलेल्या भाषांमध्ये धावण्याच्या वेळेस ऑब्जेक्टचे प्रकार व्यवस्थापित करण्याचा फायदा होतो. हे आम्हाला प्रोग्रेस कंस्ट्रक्टरकडून टायपिंग हटविण्याची परवानगी देते आणि कोड कार्य करत राहील.

वर्ग प्रगती {

     खाजगी $ फाईल

     फंक्शन __ कॉन्स्ट्रक्ट ($ फाईल) {
         $ या-> फाईल = $ फाईल;
     }

    फंक्शन getAsPercent () {
         परत $ या-> फाइल-> * 100 / / या-> फाइल-> लांबी पाठविली;
     }

}

आम्ही आता प्रोग्रेस येथे काहीही लॉन्च करू शकतो. आणि काहीही करून, मी शब्दशः काहीही म्हणायचे आहे:

वर्ग संगीत {

सार्वजनिक-लांबी;
सार्वजनिक-पाठविले;

सार्वजनिक $ कलाकार;
सार्वजनिक $ अल्बम;
पब्लिक $ रिलीझ डेट;

अल्बमकव्हरफाईल () function फंक्शन मिळवा
'प्रतिमा / कव्हर्स /' परत करा. $ हा-> कलाकार. '/'. $ हे-> अल्बम. '.png';
}
}

आणि वरील प्रमाणे संगीत वर्ग उत्तम प्रकारे कार्य करेल. आपण फाईल प्रमाणेच चाचणीद्वारे ही सहज चाचणी घेऊ शकतो.
फंक्शन टेस्टआयटीकेनगेटटप्रोग्रेसऑफॅम्यूझिकस्ट्रीमएस्पर्सेंट () {
$ संगीत = नवीन संगीत ();
$ संगीत-> लांबी = 200;
$ संगीत-> पाठविलेले = 100;

$ प्रगती = नवीन प्रगती ($ संगीत);

$ हे-> assertEquals (50, $ प्रगती-> getAsPercent ());
}

तर मुळात कोणतीही मोजण्यायोग्य सामग्री प्रगती वर्गासह वापरली जाऊ शकते. व्हेरिएबलचे नाव बदलून कोडमध्येही व्यक्त केले पाहिजे.

वर्ग प्रगती {

खाजगी-मोजमाप करणारी सामग्री;

कार्य __संरचना ($ मोजण्यायोग्य सामग्री)
$ this-> پیم्यशील कंटेन्ट = $ मोजण्यायोग्य सामग्री;
}

फंक्शन getAsPercent () {
परतावा $ या-> मोजण्यायोग्य कंटेन्ट-> पाठविला * 100 / $ हे-> मोजण्यायोग्य कंटेन्ट-> लांबी;
}

}

जेव्हा आम्ही फाईल टाईपंट म्हणून निर्दिष्ट केले, तेव्हा आम्ही आमचा वर्ग काय हाताळू शकतो याबद्दल आशावादी होतो. ते स्पष्ट होते आणि इतर काहीही आले तर एक मोठी चूक आम्हाला सांगत असे.

Uबेस क्लासची पध्दत अधिलिखित करणारे ना क्लास जे बेस क्लास कॉन्ट्रॅक्ट मिळवतात त्यानुसार क्लास कॉन्ट्रॅक्ट केले जात नाही. 

आमच्या कराराला अनुरूप नसलेल्या ऑब्जेक्ट्सवर पद्धती कॉल करण्याचा किंवा फील्डमध्ये प्रवेश करण्याचा प्रयत्न आम्ही करू इच्छित नाही. जेव्हा आमच्याकडे टाइपसिंट होता तेव्हा त्याद्वारे करार निर्दिष्ट केला होता. फाईल वर्गाची फील्ड आणि पद्धती. आता आपल्याकडे काहीही नसल्याने आम्ही काहीही पाठवू शकतो, स्ट्रिंग देखील देऊ शकतो आणि यामुळे एक वाईट त्रुटी येईल.

दोन्ही प्रकरणांमध्ये अंतिम परिणाम सारखाच असला, म्हणजे कोड खंडित झाला, तरी पूर्वीने एक छान संदेश दिला. तथापि, हे खूप गडद आहे. व्हेरिएबल काय आहे - आमच्या बाबतीत एक स्ट्रिंग - आणि कोणते गुणधर्म शोधले गेले आणि सापडले नाहीत हे जाणून घेण्याचा कोणताही मार्ग नाही. डीबग करणे आणि समस्येचे निराकरण करणे कठीण आहे. प्रोग्रामरने प्रोग्रेस क्लास उघडणे आवश्यक आहे, ते वाचणे आणि समजून घेणे आवश्यक आहे. करार, या प्रकरणात, जेव्हा तुम्ही टाईपहिंट स्पष्टपणे निर्दिष्ट करत नाही, तेव्हा आहे defiप्रगतीच्या वर्तनाने निश्‍चित. हा एक गर्भित करार आहे जो केवळ प्रगतीसाठी ओळखला जातो. आमच्या उदाहरणात, ते आहे defigetAsPercent() पद्धतीत दोन फील्ड, पाठवलेले आणि लांबी, ऍक्सेस करून nished. वास्तविक जीवनात निहित करार अतिशय गुंतागुंतीचा आणि वर्गात फक्त काही सेकंद शोधून शोधणे कठीण असू शकते.

खाली दिलेल्या इतर कोणत्याही टिपा सहजपणे लागू केल्या जाऊ शकत नाहीत किंवा प्रयत्नाची हमी न देणार्‍या गंभीर वास्तूविषयक बदलांना त्रास देत असल्यासच या निराकरणाची शिफारस केली जाते.

Ercole Palmeri

इनोव्हेशन वृत्तपत्र
नवोपक्रमावरील सर्वात महत्त्वाच्या बातम्या चुकवू नका. त्यांना ईमेलद्वारे प्राप्त करण्यासाठी साइन अप करा.

अलीकडील लेख

यूके अँटिट्रस्ट रेग्युलेटरने GenAI वर BigTech अलार्म वाढवला

UK CMA ने आर्टिफिशियल इंटेलिजन्स मार्केटमध्ये बिग टेकच्या वर्तनाबद्दल चेतावणी जारी केली आहे. तेथे…

18 एप्रिल 2024

कासा ग्रीन: इटलीमध्ये शाश्वत भविष्यासाठी ऊर्जा क्रांती

इमारतींची उर्जा कार्यक्षमता वाढविण्यासाठी युरोपियन युनियनने तयार केलेल्या "ग्रीन हाऊसेस" डिक्रीने त्याची वैधानिक प्रक्रिया पूर्ण केली आहे ...

18 एप्रिल 2024

Casaleggio Associati च्या नवीन अहवालानुसार इटलीमध्ये ईकॉमर्स +27% वर

Casaleggio Associati चा इटलीमधील ईकॉमर्सवरील वार्षिक अहवाल सादर केला. “AI-Commerce: the frontiers of Ecommerce with Artificial Intelligence” शीर्षक असलेला अहवाल.…

17 एप्रिल 2024

ब्रिलियंट आयडिया: Bandalux सादर करते Airpure®, हवा शुद्ध करणारा पडदा

पर्यावरण आणि लोकांच्या कल्याणासाठी सतत तांत्रिक नवकल्पना आणि वचनबद्धतेचा परिणाम. Bandalux सादर करते Airpure®, एक तंबू…

12 एप्रिल 2024

तुमच्या भाषेत इनोव्हेशन वाचा

इनोव्हेशन वृत्तपत्र
नवोपक्रमावरील सर्वात महत्त्वाच्या बातम्या चुकवू नका. त्यांना ईमेलद्वारे प्राप्त करण्यासाठी साइन अप करा.

आमचे अनुसरण करा