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

बंद तत्त्व उघडा
पद्धती

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

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

 

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

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

 

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

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

वापरकर्त्याचे तर्कशास्त्र

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

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

 

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

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

 

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

 

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

 

वर्ग प्रगती {

     खाजगी $ फाईल

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

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

}

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

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

पण का?

आणि कसे?

 

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

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

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

 

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

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

वर्ग प्रगती {

     खाजगी $ फाईल

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

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

}

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

वर्ग संगीत {

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

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

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

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

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

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

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

वर्ग प्रगती {

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

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

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

}

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

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

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

शेवटचा निकाल एकतर मार्गाने सारखाच असतो, कोडचा ब्रेक म्हणजेच, पूर्वने एक छान संदेश दिला. हे मात्र खूप अस्पष्ट आहे. व्हेरिएबल म्हणजे काय हे जाणून घेण्याचा कोणताही मार्ग नाही - आमच्या बाबतीत एक स्ट्रिंग - आणि कोणत्या मालमत्ता शोधल्या गेल्या आणि सापडल्या नाहीत. डिबग करणे आणि समस्येचे निराकरण करणे कठीण आहे. प्रोग्रामरला प्रोग्रेस प्रोग्रेस (क्लास) उघडावा लागेल, तो वाचून समजून घ्यावा लागेल. करारा, या प्रकरणात, जेव्हा टायपंट स्पष्टपणे निर्दिष्ट केलेले नाही, तेव्हा प्रोग्रेसच्या वर्तनाद्वारे परिभाषित केले जाते. हे एक अवतरित करार आहे, केवळ प्रगतीसाठी ज्ञात आहे. आमच्या उदाहरणात, हे getAsPercent () पद्धतीत पाठवलेल्या आणि लांबीच्या दोन फील्डमध्ये प्रवेश करून परिभाषित केले आहे. वास्तविक जीवनात, वर्गात काही सेकंद शोधून अंतर्निहित करार शोधणे खूप जटिल आणि अवघड असू शकते.

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

एर्कोले पाल्मेरी

सीव्ही एर्कोल पाल्मेरी
कोणतीही टिप्पणी नाही

Lascia एक commento

तुमचा ईमेल पत्ता प्रकाशित होणार नाही. मी मुलाखत घेण्याऐवजी मुलाखत *

व्यवसाय बुद्धिमत्ता धोरण
पद्धती
यशस्वी व्यवसाय बुद्धिमत्तेची रणनीती

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

घन घन भूमितीय आकडेवारी
प्रशिक्षण
1
ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंगची 5 तत्त्वे काय आहेत याकडे लक्ष द्या

ऑब्जेक्ट-देणारं डिझाइन (ओओडी किंवा ओओपी) च्या पाच तत्त्वांचा संदर्भ घेऊन सोलिड एक परिवर्णी शब्द आहे. हे मार्गदर्शक तत्त्वे आहेत जी विकासक सॉफ्टवेअर तयार करण्यासाठी वापरू शकतात जे व्यवस्थापित करणे, देखभाल करणे आणि वाढविणे सोपे आहे. या संकल्पना समजून घेतल्याने आपण एक उत्कृष्ट विकसक बनू शकाल आणि आपल्याला ...

इनोव्हेशन अर्थ
पद्धती
नूतनीकरण सुरू करण्यासाठी 4 (व्यावहारिक) चरण

हे काही रहस्य नाहीः कोरोनाव्हायरस (साथीचा रोग) सर्व देशभर (किंवा खंडभर) असलेला रोगराईने बर्‍याच लोकांचे जीवन बदलले आहे. एका दिवसापासून दुस to्या दिवसापर्यंत आम्ही स्वत: ला काम न करता किंवा नवीन काहीतरी करण्याची गरज असलेल्या नवख्याला जीवन देण्याची गरज असल्याचे आढळले. या लेखामध्ये आम्ही आपल्याला देऊ इच्छित असलेल्या 4 सोप्या चरणांची शिफारस करुन आपली मदत करू इच्छितो ...