Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

मजबूत रूबी एप्लिकेशन के लिए SOLID डिज़ाइन सिद्धांतों में महारत हासिल करें

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

  • यह गतिहीनता का कारण बनता है।
  • कोड बदलना महंगा है।
  • सॉफ्टवेयर को सरल बनाने की तुलना में अधिक जटिलता जोड़ना आसान है।
  • कोड अनियंत्रणीय है।
  • एक डेवलपर के लिए यह पता लगाने में बहुत समय लगता है कि इसकी कार्यक्षमताएं कैसे काम करती हैं।
  • सॉफ्टवेयर के एक हिस्से को बदलने से आमतौर पर दूसरा टूट जाता है, और हम यह अनुमान नहीं लगा सकते कि परिवर्तन क्या समस्याएं ला सकता है।

पेपर डिज़ाइन प्रिंसिपल्स एंड डिज़ाइन पैटर्न्स, सड़ते सॉफ्टवेयर के निम्नलिखित लक्षणों को सूचीबद्ध करता है:

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

सॉफ्टवेयर को इस तरह डिजाइन करना आवश्यक है कि परिवर्तनों को नियंत्रित और अनुमानित किया जा सके।

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

निर्भरता उलटा सॉफ्टवेयर मॉड्यूल को डिकपल करने के लिए लागू एक सिद्धांत है।

एक हाई-लेवल मॉड्यूल को लो-लेवल मॉड्यूल पर निर्भर नहीं करना चाहिए; दोनों को अमूर्तता पर निर्भर करना चाहिए।

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

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

मजबूत रूबी एप्लिकेशन के लिए SOLID डिज़ाइन सिद्धांतों में महारत हासिल करें

ऊपर हमारे उदाहरण में, 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 किस प्रकार की समस्याओं को हल करता है और हम यह क्यों कर रहे हैं। समस्या को समझने से आपको डिजाइन सिद्धांतों को अपनाने और बेहतर सॉफ्टवेयर डिजाइन करने में मदद मिलती है।

  1. पेशेवर आर्किटेक्ट्स के लिए 5 अनिवार्य सॉफ्टवेयर टूल्स पेशेवर आर्किटेक्ट्स के लिए 5 अनिवार्य सॉफ्टवेयर टूल्स

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

  1. शीर्ष मुफ्त गेम डिज़ाइन सॉफ्टवेयर - कोडिंग की आवश्यकता नहीं शीर्ष मुफ्त गेम डिज़ाइन सॉफ्टवेयर - कोडिंग की आवश्यकता नहीं

    पहले अगर आप गेम डेवलपर बनना चाहते थे, तो आपको JAVA, ActionScript, C++ जैसी कुछ प्रोग्रामिंग भाषाएं सीखनी पड़ती थीं। चूंकि ये प्रोग्रामिंग भाषाएं डेवलपर को 2D या 3D गेम बनाने में मदद करती हैं। हालांकि, अब बहुत सारे गेम डिज़ाइनिंग सॉफ्टवेयर उपलब्ध हैं जिनके साथ कोडिंग आवश्यक नहीं है। इसलिए, टूल्स में

  1. 2022 के टॉप 10 बुक डिज़ाइन सॉफ्टवेयर टूल्स - शानदार कवर और लेआउट बनाएं 2022 के टॉप 10 बुक डिज़ाइन सॉफ्टवेयर टूल्स - शानदार कवर और लेआउट बनाएं

    बुक डिज़ाइन सॉफ्टवेयर का उपयोग लेखक और ऑथर्स ऑनलाइन बुक बनाने के लिए कर सकते हैं। कई ऐसे एप्लिकेशन हैं जिनका उपयोग नौसिखियों और विशेषज्ञों दोनों द्वारा किया जा सकता है। यह लेख बुक कवर और इंटरनल डिज़ाइन बनाने और अपनी बुक को डिजिटल फॉर्मेट में सेव करने के लिए पेड और फ्री दोनों बुक डिज़ाइन सॉफ्टवेयर पर