सभी सॉफ्टवेयर एप्लिकेशन समय के साथ बदलते हैं। सॉफ्टवेयर में किए गए परिवर्तन अप्रत्याशित कैस्केडिंग मुद्दों का कारण बन सकते हैं। हालांकि, परिवर्तन अपरिहार्य है, क्योंकि हम ऐसा सॉफ्टवेयर नहीं बना सकते जो न बदलें। सॉफ्टवेयर आवश्यकताएं सॉफ्टवेयर के बढ़ने के साथ बदलती रहती हैं। हम जो कर सकते हैं वह सॉफ्टवेयर को इस तरह डिजाइन करना है कि यह परिवर्तन के प्रति लचीला हो। सॉफ्टवेयर को ठीक से डिजाइन करने में शुरुआत में समय और मेहनत लग सकती है, लेकिन लंबे समय में, यह समय और मेहनत बचाता है। टाइटली कपल्ड सॉफ्टवेयर नाजुक होता है, और हम परिवर्तन के साथ क्या होता है इसकी भविष्यवाणी नहीं कर सकते। खराब डिजाइन किए गए सॉफ्टवेयर के कुछ प्रभाव यहां दिए गए हैं:
- यह गतिहीनता का कारण बनता है।
- कोड बदलना महंगा है।
- सॉफ्टवेयर को सरल बनाने की तुलना में अधिक जटिलता जोड़ना आसान है।
- कोड अनियंत्रणीय है।
- एक डेवलपर के लिए यह पता लगाने में बहुत समय लगता है कि इसकी कार्यक्षमताएं कैसे काम करती हैं।
- सॉफ्टवेयर के एक हिस्से को बदलने से आमतौर पर दूसरा टूट जाता है, और हम यह अनुमान नहीं लगा सकते कि परिवर्तन क्या समस्याएं ला सकता है।
पेपर डिज़ाइन प्रिंसिपल्स एंड डिज़ाइन पैटर्न्स, सड़ते सॉफ्टवेयर के निम्नलिखित लक्षणों को सूचीबद्ध करता है:
- कठोरता: समस्याएं पैदा किए बिना कोड बदलना बहुत मुश्किल है, क्योंकि कोड के एक हिस्से में परिवर्तन करने से कोड के अन्य हिस्सों में परिवर्तन करने की आवश्यकता होती है।
- नाजुकता: कोड बदलने से आमतौर पर सॉफ्टवेयर का व्यवहार टूट जाता है। यह उन हिस्सों को भी तोड़ सकता है जो परिवर्तन से सीधे संबंधित नहीं हैं।
- गतिहीनता: हालांकि सॉफ्टवेयर एप्लिकेशन के कुछ हिस्सों में समान व्यवहार हो सकता है, हम कोड का पुन: उपयोग करने में असमर्थ हैं और उन्हें डुप्लिकेट करना होगा।
- श्यानता: जब सॉफ्टवेयर को बदलना मुश्किल होता है, तो हम इसे बेहतर बनाने के बजाय सॉफ्टवेयर में जटिलता जोड़ते रहते हैं।
सॉफ्टवेयर को इस तरह डिजाइन करना आवश्यक है कि परिवर्तनों को नियंत्रित और अनुमानित किया जा सके।
SOLID डिजाइन सिद्धांत सॉफ्टवेयर प्रोग्राम को डिकपल करके इन मुद्दों को हल करने में मदद करते हैं। रॉबर्ट सी. मार्टिन ने इन अवधारणाओं को अपने पेपर डिज़ाइन प्रिंसिपल्स एंड डिज़ाइन पैटर्न्स में पेश किया, और माइकल फीदर्स बाद में संक्षिप्त नाम लेकर आए।
SOLID डिजाइन सिद्धांत में ये पांच सिद्धांत शामिल हैं:
- Single Responsibility Principle (एकल उत्तरदायित्व सिद्धांत)
- Open/Closed Principle (खुला/बंद सिद्धांत)
- Liskov Substitution Principle (लिस्कोव प्रतिस्थापन सिद्धांत)
- Interface Segregation Principle (इंटरफ़ेस पृथक्करण सिद्धांत)
- Dependency Inversion Principle (निर्भरता उलटा सिद्धांत)
हम रूबी में अच्छी तरह से डिजाइन किए गए सॉफ्टवेयर बनाने में इन सिद्धांतों की मदद को समझने के लिए उनमें से प्रत्येक का पता लगाएंगे।
एकल उत्तरदायित्व सिद्धांत - SRP
मान लें कि HR प्रबंधन सॉफ्टवेयर के लिए, हमें उपयोगकर्ता बनाने, कर्मचारी का वेतन जोड़ने, और कर्मचारी का वेतन पर्ची उत्पन्न करने की कार्यक्षमता की आवश्यकता है। इसे बनाते समय, हम इन कार्यक्षमताओं को एक ही क्लास में जोड़ सकते हैं, लेकिन यह दृष्टिकोण इन कार्यक्षमताओं के बीच अवांछित निर्भरता का कारण बनता है। यह शुरू में सरल है, लेकिन जब चीजें बदलती हैं और नई आवश्यकताएं उत्पन्न होती हैं, तो हम यह अनुमान लगाने में असमर्थ होंगे कि परिवर्तन किन कार्यक्षमताओं को तोड़ देगा।
एक क्लास के पास बदलने का एक, और केवल एक कारण होना चाहिए - रॉबर्ट सी मार्टिन
यहाँ एक नमूना कोड है जहां सभी कार्यक्षमता एक ही क्लास में है:
class User
def initialize(employee, month)
@employee = employee
@month = month
end
def generate_payslip
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
# और इसे एक फाइल में लिखें
self.send_email
end
def send_email
# ईमेल भेजने का कोड
employee.email
month
end
end
वेतन पर्ची उत्पन्न करने और इसे उपयोगकर्ता को भेजने के लिए, हम क्लास को इनिशियलाइज़ कर सकते हैं और generate payslip मेथड को कॉल कर सकते हैं:
month = 11
user = User.new(employee, month)
user.generate_payslip
अब, एक नई आवश्यकता है। हम वेतन पर्ची उत्पन्न करना चाहते हैं लेकिन ईमेल नहीं भेजना चाहते। हमें मौजूदा कार्यक्षमता को वैसे ही रखने की आवश्यकता है और आंतरिक रिपोर्टिंग के लिए बिना ईमेल भेजे एक नया वेतन पर्ची जनरेटर जोड़ना होगा, क्योंकि यह आंतरिक उद्देश्य के लिए है। इस चरण के दौरान, हम यह सुनिश्चित करना चाहते हैं कि कर्मचारियों को भेजी गई मौजूदा वेतन पर्ची कार्यात्मक बनी रहे।
इस आवश्यकता के लिए, हम मौजूदा कोड का पुन: उपयोग नहीं कर सकते। हमें या तो generate_payslip मेथड में एक फ्लैग जोड़ना होगा जो कहे कि यदि सच है तो ईमेल भेजें अन्यथा नहीं। यह किया जा सकता है, लेकिन चूंकि यह मौजूदा कोड को बदलता है, यह मौजूदा कार्यक्षमता को तोड़ सकता है।
यह सुनिश्चित करने के लिए कि हम चीजों को नहीं तोड़ते, हमें इन तर्कों को अलग-अलग क्लासेस में डिकपल करने की आवश्यकता है:
class PayslipGenerator
def initialize(employee, month)
@employee = employee
@month = month
end
def generate_payslip
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
# और इसे एक फाइल में लिखें
end
end
class PayslipMailer
def initialize(employee)
@employee = employee
end
def send_mail
# ईमेल भेजने का कोड
employee.email
month
end
end
अब, हम इन दो क्लासेस को इनिशियलाइज़ कर सकते हैं और उनके मेथड्स को कॉल कर सकते हैं:
month = 11
# सामान्य वेतन पर्ची जनरेटर
generator = PayslipGenerator.new(employee, month)
generator.generate_payslip
# ईमेल भेजें
mailer = PayslipMailer.new(employee, month)
mailer.send_mail
यह दृष्टिकोण जिम्मेदारियों को डिकपल करने में मदद करता है और एक अनुमानित परिवर्तन सुनिश्चित करता है। यदि हमें केवल मेलर कार्यक्षमता बदलने की आवश्यकता है, तो हम रिपोर्ट जनरेशन को बदले बिना ऐसा कर सकते हैं। यह कार्यक्षमता में किसी भी परिवर्तन की भविष्यवाणी करने में भी मदद करता है।
मान लीजिए हमें ईमेल में महीने फ़ील्ड के प्रारूप को 11 के बजाय Nov में बदलने की आवश्यकता है। इस मामले में, हम PayslipMailer क्लास को संशोधित करेंगे, और यह सुनिश्चित करेगा कि PayslipGenerator कार्यक्षमता में कुछ भी नहीं बदलेगा या टूटेगा।
हर बार जब आप कोड का एक टुकड़ा लिखते हैं, तो बाद में एक प्रश्न पूछें। इस क्लास की जिम्मेदारी क्या है? यदि आपके उत्तर में "और" है, तो क्लास को कई क्लासेस में विभाजित करें। छोटी क्लासेस हमेशा बड़ी, सामान्य क्लासेस से बेहतर होती हैं।
खुला/बंद सिद्धांत - OCP
बर्ट्रेंड मेयर ने अपनी पुस्तक ऑब्जेक्ट-ओरिएंटेड सॉफ्टवेयर कंस्ट्रक्शन में खुला/बंद सिद्धांत की शुरुआत की।
सिद्धांत कहता है, "सॉफ्टवेयर एंटिटीज़ (क्लासेस, मॉड्यूल्स, फंक्शन्स, आदि) विस्तार के लिए खुली होनी चाहिए लेकिन संशोधन के लिए बंद"। इसका मतलब है कि हमें एंटिटी को बदले बिना व्यवहार बदलने में सक्षम होना चाहिए।
ऊपर के उदाहरण में, हमारे पास एक कर्मचारी के लिए वेतन पर्ची भेजने की कार्यक्षमता है, लेकिन यह सभी कर्मचारियों के लिए बहुत सामान्य है। हालांकि, एक नई आवश्यकता उत्पन्न होती है: कर्मचारी के प्रकार के आधार पर वेतन पर्ची उत्पन्न करें। हमें पूर्णकालिक कर्मचारियों और ठेकेदारों के लिए अलग-अलग पेरोल जनरेशन लॉजिक की आवश्यकता है। इस मामले में, हम मौजूदा PayrollGenerator को संशोधित कर सकते हैं और इन कार्यक्षमताओं को जोड़ सकते हैं:
class PayslipGenerator
def initialize(employee, month)
@employee = employee
@month = month
end
def generate_payslip
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
if employee.contractor?
# ठेकेदार के लिए वेतन पर्ची उत्पन्न करें
else
# एक सामान्य वेतन पर्ची उत्पन्न करें
end
# और इसे एक फाइल में लिखें
end
end
हालांकि, यह एक बुरा पैटर्न है। ऐसा करके, हम मौजूदा क्लास को संशोधित कर रहे हैं। यदि हमें कर्मचारी अनुबंधों के आधार पर अधिक जनरेशन लॉजिक जोड़ने की आवश्यकता है, तो हमें मौजूदा क्लास को संशोधित करने की आवश्यकता है, लेकिन ऐसा करना खुला/बंद सिद्धांत का उल्लंघन करता है। क्लास को संशोधित करके, हम अनपेक्षित परिवर्तन करने का जोखिम उठाते हैं। जब कुछ बदलता है या जोड़ा जाता है, तो यह मौजूदा कोड में अज्ञात मुद्दों का कारण बन सकता है। ये if-else एक ही क्लास के अधिक स्थानों में हो सकते हैं। इसलिए, जब हम एक नया कर्मचारी प्रकार जोड़ते हैं, तो हम उन स्थानों को याद कर सकते हैं जहां ये if-else मौजूद हैं। उन सभी को ढूंढना और संशोधित करना जोखिम भरा हो सकता है और समस्या पैदा कर सकता है।
हम इस कोड को इस तरह रीफैक्टर कर सकते हैं कि हम एंटिटी को बदले बिना कार्यक्षमता जोड़कर विस्तार कर सकें। तो, आइए इनमें से प्रत्येक के लिए एक अलग क्लास बनाएं और उन सभी के लिए समान generate मेथड रखें:
class ContractorPayslipGenerator
def initialize(employee, month)
@employee = employee
@month = month
end
def generate
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
# और इसे एक फाइल में लिखें
end
end
class FullTimePayslipGenerator
def initialize(employee, month)
@employee = employee
@month = month
end
def generate
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
# और इसे एक फाइल में लिखें
end
सुनिश्चित करें कि इनमें समान मेथड नाम है। अब, PayslipGenerator क्लास को इन क्लासेस का उपयोग करने के लिए बदलें:
GENERATORS = {
'full_time' => FullTimePayslipGenerator,
'contractor' => ContractorPayslipGenerator
}
class PayslipGenerator
def initialize(employee, month)
@employee = employee
@month = month
end
def generate_payslip
# डेटाबेस से पढ़ने का कोड,
# वेतन पर्ची उत्पन्न करें
GENERATORS[employee.type].new(employee, month).generate()
# और इसे एक फाइल में लिखें
end
end
यहां, हमारे पास एक GENERATORS कॉन्स्टेंट है जो कर्मचारी प्रकार के आधार पर कॉल की जाने वाली क्लास को मैप करता है। हम इसका उपयोग यह निर्धारित करने के लिए कर सकते हैं कि किस क्लास को कॉल करना है। अब, जब हमें नई कार्यक्षमता जोड़नी होती है, तो हम बस उसके लिए एक नई क्लास बना सकते हैं और इसे GENERATORS कॉन्स्टेंट में जोड़ सकते हैं। यह क्लास को कुछ तोड़े बिना या मौजूदा तर्क के बारे में सोचे बिना विस्तारित करने में मदद करता है। हम किसी भी प्रकार के वेतन पर्ची जनरेटर को आसानी से जोड़ या हटा सकते हैं।
लिस्कोव प्रतिस्थापन सिद्धांत - LSP
लिस्कोव प्रतिस्थापन सिद्धांत कहता है, "यदि S, T का सबटाइप है, तो T टाइप के ऑब्जेक्ट्स को S टाइप के ऑब्जेक्ट्स से बदला जा सकता है"।
इस सिद्धांत को समझने के लिए, आइए पहले समस्या को समझें। खुला/बंद सिद्धांत के तहत, हमने सॉफ्टवेयर को इस तरह डिजाइन किया कि इसे विस्तारित किया जा सके। हमने एक सबक्लास वेतन पर्ची जनरेटर बनाया जो एक विशिष्ट काम करता है। कॉलर के लिए, वे जिस क्लास को कॉल कर रहे हैं वह अज्ञात है। इन क्लासेस का व्यवहार समान होना चाहिए ताकि कॉलर अंतर न बता सके। व्यवहार से, हमारा मतलब है कि क्लास में मेथड्स सुसंगत होने चाहिए। इन क्लासेस में मेथड्स में निम्नलिखित विशेषताएं होनी चाहिए:
- समान नाम हो
- समान संख्या में तर्क लें जिनका डेटा प्रकार समान हो
- समान डेटा प्रकार लौटाएं
आइए वेतन पर्ची जनरेटर के उदाहरण को देखें। हमारे पास दो जनरेटर हैं, एक पूर्णकालिक कर्मचारियों के लिए और दूसरा ठेकेदारों के लिए। अब, यह सुनिश्चित करने के लिए कि इन वेतन पर्चियों का व्यवहार सुसंगत है, हमें उन्हें एक बेस क्लास से इनहेरिट करने की आवश्यकता है। आइए User नामक एक बेस क्लास परिभाषित करें।
class User
def generate
end
end
खुला/बंद सिद्धांत के उदाहरण में हमने जो सबक्लास बनाया था, उसका बेस क्लास नहीं था। हम इसे बेस क्लास User के साथ संशोधित करते हैं:
class ContractorPayslipGenerator < User
def generate
# वेतन पर्ची उत्पन्न करने का कोड
end
end
class FullTimePayslipGenerator < User
def generate
# वेतन पर्ची उत्पन्न करने का कोड
end
end
अब, हम उन मेथड्स का एक सेट परिभाषित करते हैं जो User क्लास को इनहेरिट करने वाले किसी भी सबक्लास के लिए आवश्यक हैं। हम इन मेथड्स को बेस क्लास में परिभाषित करते हैं। हमारे मामले में, हमें केवल एक मेथड की आवश्यकता है, जिसे generate कहा जाता है।
class User
def generate
raise "NotImplemented"
end
end
यहां, हमने generate मेथड को परिभाषित किया है, जिसमें एक raise स्टेटमेंट है। इसलिए, बेस क्लास को इनहेरिट करने वाले किसी भी सबक्लास में generate मेथड होना चाहिए। यदि यह मौजूद नहीं है, तो यह एक त्रुटि उठाएगा कि मेथड लागू नहीं है। इस तरह, हम सुनिश्चित कर सकते हैं कि सबक्लास सुसंगत है। इसके साथ, कॉलर हमेशा सुनिश्चित हो सकता है कि generate मेथड मौजूद है।
यह सिद्धांत किसी भी सबक्लास को आसानी से प्रतिस्थापित करने में मदद करता है बिना चीजों को तोड़े और बहुत सारे परिवर्तन करने की आवश्यकता के बिना।
इंटरफ़ेस पृथक्करण सिद्धांत - ISP
इंटरफ़ेस पृथक्करण सिद्धांत स्टेटिक भाषाओं पर लागू होता है, और चूंकि रूबी एक डायनामिक भाषा है, इसलिए इंटरफ़ेस की कोई अवधारणा नहीं है। इंटरफ़ेस क्लासेस के बीच अमूर्त नियमों को परिभाषित करते हैं।
सिद्धांत कहता है,
क्लाइंट्स को उन इंटरफ़ेस पर निर्भर करने के लिए मजबूर नहीं किया जाना चाहिए जिनका वे उपयोग नहीं करते। - रॉबर्ट सी. मार्टिन
इसका मतलब है कि एक सामान्यीकृत इंटरफ़ेस के बजाय कई इंटरफ़ेस होना बेहतर है जिसका उपयोग कोई भी क्लास कर सकता है। यदि हम एक सामान्यीकृत इंटरफ़ेस परिभाषित करते हैं, तो क्लास को उस परिभाषा पर निर्भर रहना पड़ता है जिसका वह उपयोग नहीं करता।
रूबी में इंटरफ़ेस नहीं हैं, लेकिन आइए क्लास और सबक्लास अवधारणा को देखें ताकि कुछ समान बनाया जा सके।
लिस्कोव प्रतिस्थापन सिद्धांत के लिए उपयोग किए गए उदाहरण में, हमने देखा कि सबक्लास FullTimePayslipGenerator को सामान्य क्लास User से इनहेरिट किया गया था। लेकिन User एक बहुत ही सामान्य क्लास है और इसमें अन्य मेथड्स हो सकते हैं। यदि हमें एक और कार्यक्षमता होनी चाहिए, जैसे Leave, तो यह User का सबक्लास होना होगा। Leave को generate मेथड की आवश्यकता नहीं है, लेकिन यह इस मेथड पर निर्भर होगा। इसलिए, एक सामान्य क्लास होने के बजाय, हम इसके लिए एक विशिष्ट क्लास रख सकते हैं:
class Generator
def generate
raise "NotImplemented"
end
end
class ContractorPayslipGenerator < Generator
def generate
# वेतन पर्ची उत्पन्न करने का कोड
end
end
class FullTimePayslipGenerator < Generator
def generate
# वेतन पर्ची उत्पन्न करने का कोड
end
end
यह जनरेटर वेतन पर्ची जनरेशन के लिए विशिष्ट है, और सबक्लास को सामान्य User क्लास पर निर्भर नहीं होना पड़ता।
निर्भरता उलटा सिद्धांत - DIP
निर्भरता उलटा सॉफ्टवेयर मॉड्यूल को डिकपल करने के लिए लागू एक सिद्धांत है।
एक हाई-लेवल मॉड्यूल को लो-लेवल मॉड्यूल पर निर्भर नहीं करना चाहिए; दोनों को अमूर्तता पर निर्भर करना चाहिए।
उपरोक्त सिद्धांतों का उपयोग करके डिजाइन हमें निर्भरता उलटा सिद्धांत की ओर मार्गदर्शन करता है। किसी भी क्लास जिसका एकल उत्तरदायित्व है, उसे काम करने के लिए अन्य क्लासेस से चीजों की आवश्यकता होती है। वेतन पर्ची उत्पन्न करने के लिए, हमें डेटाबेस तक पहुंच की आवश्यकता होती है, और रिपोर्ट जनरेट होने के बाद हमें फाइल में लिखने की आवश्यकता होती है। एकल उत्तरदायित्व सिद्धांत के साथ, हम एक क्लास के लिए केवल एक काम रखने की कोशिश कर रहे हैं। लेकिन, डेटाबेस से पढ़ने और फाइल में लिखने जैसी चीजों को उसी क्लास के भीतर करने की आवश्यकता होती है।
इन निर्भरताओं को हटाना और मुख्य व्यावसायिक तर्क को डिकपल करना महत्वपूर्ण है। यह कोड को परिवर्तन के दौरान तरल रहने में मदद करेगा, और परिवर्तन अनुमानित हो जाता है। निर्भरता को उलटा करने की आवश्यकता है, और मॉड्यूल के कॉलर का निर्भरता पर नियंत्रण होना चाहिए। हमारे वेतन पर्ची जनरेटर में, निर्भरता रिपोर्ट के लिए डेटा का स्रोत है; इस कोड को इस तरह व्यवस्थित किया जाना चाहिए कि कॉलर स्रोत निर्दिष्ट कर सके। निर्भरता का नियंत्रण उलटा होना चाहिए और कॉलर द्वारा आसानी से संशोधित किया जा सकता है।

ऊपर हमारे उदाहरण में, ContractorPayslipGenerator मॉड्यूल निर्भरता को नियंत्रित करता है, क्योंकि यह निर्धारित करता है कि डेटा कहां से पढ़ना है और आउटपुट को कैसे स्टोर करना है। इसे उलटने के लिए, आइए एक UserReader क्लास बनाएं जो यूजर डेटा पढ़ता है:
class UserReader
def get
raise "NotImplemented"
end
end
अब, मान लीजिए हम चाहते हैं कि यह Postgres से डेटा पढ़े। हम इस उद्देश्य के लिए UserReader का एक सबक्लास बनाते हैं:
class PostgresUserReader < UserReader
def get
# Postgres से डेटा पढ़ने का कोड
end
इसी तरह, हमारे पास FileUserReader, InMemoryUserReader, या हम जो चाहें उस प्रकार का कोई अन्य रीडर हो सकता है। अब हमें FullTimePayslipGenerator क्लास को संशोधित करने की आवश्यकता है ताकि यह PostgresUserReader को निर्भरता के रूप में उपयोग करे।
class FullTimePayslipGenerator < Generator
def initialize(datasource)
@datasource = datasource
end
def generate
# वेतन पर्ची उत्पन्न करने का कोड
data = datasource.get()
end
end
कॉलर अब PostgresUserReader को निर्भरता के रूप में पास कर सकता है:
datasource = PostgresUserReader.new()
FullTimePayslipGenerator.new(datasource)
कॉलर का अब निर्भरता पर नियंत्रण है और जरूरत पड़ने पर स्रोत को आसानी से बदल सकता है।
निर्भरता को उलटना केवल क्लासेस पर लागू नहीं होता। हमें कॉन्फ़िगरेशन को भी उलटने की आवश्यकता है। उदाहरण के लिए, Postgres सर्वर से कनेक्ट करते समय, हमें विशिष्ट कॉन्फ़िगरेशन की आवश्यकता होती है, जैसे DBURL, उपयोगकर्ता नाम, और पासवर्ड। इन कॉन्फ़िगरेशन को क्लास में हार्डकोड करने के बजाय, हमें उन्हें कॉलर से पास करने की आवश्यकता है।
class PostgresUserReader < UserReader
def initialize(config)
config = config
end
def get
# कॉन्फ़िगरेशन के साथ DB इनिशियलाइज़ करें
self.config
# Postgres से डेटा पढ़ने का कोड
end
end
कॉलर द्वारा कॉन्फ़िगरेशन प्रदान करें:
config = { url: "url", user: "user" }
datasource = PostgresUserReader.new(config)
FullTimePayslipGenerator.new(datasource)
कॉलर का अब निर्भरता पर पूरा नियंत्रण है, और परिवर्तन प्रबंधन आसान और कम दर्दनाक है।
निष्कर्ष
SOLID डिजाइन कोड को डिकपल करने और परिवर्तन को कम दर्दनाक बनाने में मदद करता है। प्रोग्राम को इस तरह डिजाइन करना महत्वपूर्ण है कि वे डिकपल्ड, पुन: प्रयोज्य, और परिवर्तन के प्रति उत्तरदायी हों। सभी पांच SOLID सिद्धांत एक दूसरे के पूरक हैं और सह-अस्तित्व में होने चाहिए। एक अच्छी तरह से डिजाइन किया गया कोडबेस लचीला, बदलने में आसान, और काम करने में मजेदार होता है। कोई भी नया डेवलपर इसमें कूद सकता है और आसानी से कोड को समझ सकता है।
यह वास्तव में महत्वपूर्ण है कि आप समझें कि SOLID किस प्रकार की समस्याओं को हल करता है और हम यह क्यों कर रहे हैं। समस्या को समझने से आपको डिजाइन सिद्धांतों को अपनाने और बेहतर सॉफ्टवेयर डिजाइन करने में मदद मिलती है।