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

परिप्रेक्ष्य के एक साधारण परिवर्तन के साथ स्पेगेटी कोड को सुलझाएं

if . की वह विशाल गड़बड़ी बयान आपको चेहरे पर घूरते रहते हैं। आपको ऐसा लगता है कि आपको चाहिए इसे सरल बनाने में सक्षम हो, सिवाय उस व्यावसायिक तर्क के जो बीच में आता रहता है।

उदाहरण के लिए, मान लें कि आपके पास एक बिक्री मंच है जहां आप Quote बनाते हैं s, जिसमें कई LineItem हैं एस। इसके अलावा, आपके पास डुप्लीकेट लाइन आइटम के साथ एक कोट हो सकता है यदि वे विज्ञापन . हैं , लेकिन यदि आपके पास एकाधिक वेबसाइट हैं , आपको कीमतों को एक साथ जोड़ना होगा और इसे एक पंक्ति वस्तु के रूप में दिखाना होगा। ओह और साथ ही, यदि आप एक वेबसाइट खरीदते हैं और आपके उद्धरण में पहले से ही पांच विज्ञापन हैं, तो आपको उन्हें वेबसाइट पर 20% की छूट देनी होगी।

मैं आपको यहां से खिड़की से अपना लैपटॉप फेंकते हुए सुन सकता हूं।

आप कर सकते थे if . का एक गुच्छा लिखें इन नियमों को संभालने के लिए बयान:

class Quote
  attr_accessor :line_items
 
  ... 
 
  def add_line_item(line_item)
    if line_item.kind_of?(Ad)
      self.line_items << line_item
    elsif line_item.kind_of?(Website)
      if @line_items.select {|item| item.kind_of?(Ad) }.length >= 5
        # TODO: Put the fractions of a cent into a bank account
        # I have set up
        line_item.price *= 0.8
      end
      existing_website = self.line_items.detect { |item| item.kind_of?(Website) }
      if existing_website
        existing_website.price += line_item.price
      else
        self.line_items << line_item
      end
    end
  end
end

लेकिन मुझे लगता है कि हम सहमत हो सकते हैं कि यह बहुत ही भयानक है। आप किसी ऐसी चीज को कैसे सुलझा सकते हैं?

आप इस विधि को छोटे-छोटे तरीकों के एक समूह में विघटित कर सकते हैं, लेकिन यह आपके सभी खिलौनों को अपनी अलमारी में रखने जैसा है, ताकि आपकी माँ को लगे कि आपने अपना कमरा साफ कर लिया है। और वो kind_of? s अभी भी मुझे बहुत परेशान करेंगे।

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

अपनी विधियों को उलट दें!

कोड को रिफैक्टर करने के मेरे पसंदीदा तरीकों में से एक है कॉल करने वाले और कॉल करने वाले को उलटने का प्रयास करना। ऊपर दिए गए कोड का उपयोग करके यहां एक उदाहरण दिया गया है:

app/models/quote.rb
class Quote
  ...
  def add_line_item(line_item)
    line_item.add_to_quote(self)
  end
end
ऐप/मॉडल/line_item.rb
class Ad < LineItem
  ...
  def add_to_quote(quote)
    quote.line_items << self
  end 
end
app/models/website.rb
class Website < LineItem
  def add_to_quote(quote)
    if quote.line_items.select {|item| item.kind_of?(Ad) }.length >= 5
      # TODO: Put the fractions of a cent into a bank account
      # I have set up
      self.price *= 0.8
    end
    existing_website = quote.line_items.detect { |item| item.kind_of?(Website) }
    if existing_website
      existing_website.price += self.price
    else
	  quote.line_items << self
    end
  end
end

यह संपूर्ण नहीं है। website.rb अभी भी एक बहुत कुछ की आवश्यकता है रिफैक्टरिंग मदद की, और मैं इस बात से खुश नहीं हूं कि कैसे उलटने के तरीकों ने line_items के एनकैप्सुलेशन को तोड़ दिया ।

लेकिन आपने जटिलता की पहली परत हटा दी है। अब आप LineItem . पर कोड डाल सकते हैं या Quote , इस पर निर्भर करता है कि यह सबसे अधिक कहां समझ में आता है। LineItem ऑब्जेक्ट प्रत्येक LineItem . के बीच समानता और अंतर को संभालने के लिए इनहेरिटेंस और मिक्सिन का उपयोग कर सकते हैं उपवर्ग साथ ही, अब नया LineItem add जोड़ना वाकई आसान हो गया है अपने add_line_item . को ब्लो किए बिना उपवर्ग विधि।

आपका कोड थोड़ा साफ है, और बहुत अधिक लचीला है। तो आम तौर पर, मैं इसे जीत कहूंगा।

जहां आप शायद इस पैटर्न का उपयोग नहीं करना चाहें

उलटने का तरीका जितना उपयोगी है है, ऐसे कुछ कारण हैं जिनकी वजह से आप इस पैटर्न का उपयोग नहीं करना चाहेंगे:

  • यह इनकैप्सुलेशन को तोड़ सकता है। आपको Quote . पर विशेषताओं को उजागर करना पड़ सकता है जिसे आप सार्वजनिक रूप से उजागर नहीं करना चाहते थे।

  • यह युग्मन बढ़ा सकता है। दोनों Quote और Ad अब एक दूसरे के बारे में जानने की जरूरत है। और कितना कितना . पर निर्भर करता है उन्हें एक दूसरे के बारे में जानने की जरूरत है, यह आपके कोड को अधिक बना सकता है जटिल।

  • यह Ad पर एकल उत्तरदायित्व सिद्धांत का उल्लंघन कर सकता है , क्योंकि अब Ad यह जानने की जिम्मेदारी है कि खुद को Quote . में कैसे जोड़ा जाए ।

आप आमतौर पर इन समस्याओं के आसपास काम कर सकते हैं। लेकिन आपको उनके बारे में पता होना चाहिए, क्योंकि आप अपने कोड को बदतर! बनाने के लिए रिफैक्टरिंग नहीं चाहते हैं!

यह मेरे पसंदीदा में से एक क्यों है

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

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

इसे अपने कोड में आज़माएं

मेरे कई पसंदीदा पैटर्न की तरह, मैं पहली बार रिवर्सिंग मेथड . में आया था स्मॉलटाक बेस्ट प्रैक्टिस पैटर्न में, और तब से यह एक मूल्यवान टूल रहा है।

अगली बार जब आपको समान वस्तुओं से निपटने में कठिनाई होती है, जिनका व्यवहार थोड़ा भिन्न होता है, तो इसे आज़माएं! यदि आपको नया कोड बेहतर लगता है, तो इसे रखें। हालांकि, अगर आप ऐसा नहीं भी करते हैं, तो यह आपके दिमाग को एक ऐसे रास्ते पर ले जाएगा जो आपको बेहतर कोड की ओर ले जाएगा।


  1. रुबोकॉप के साथ लाइनिंग और ऑटो-फॉर्मेटिंग रूबी कोड

    लाइनिंग प्रोग्रामेटिक और शैलीगत त्रुटियों के लिए स्रोत कोड की स्वचालित जाँच है। यह जाँच एक स्थिर कोड विश्लेषण उपकरण द्वारा की जाती है जिसे लिंटर कहा जाता है। एक कोड फ़ॉर्मेटर, हालांकि, स्रोत कोड को स्वरूपित करने से संबंधित एक उपकरण है, ताकि यह नियमों के पूर्व-कॉन्फ़िगर किए गए सेट का सख्ती से पालन कर

  1. इस साधारण टर्मिनल ट्वीक के साथ ओएस एक्स की अधिसूचना बैनर अवधि बदलें

    जब OS X Lion को दो साल पहले जारी किया गया था, तो Apple ने एक अद्वितीय बैनर सिस्टम का उपयोग करके मैक पर पुश नोटिफिकेशन लाया। जैसा कि आप शायद पहले से ही जानते हैं, जब आप अपने मैक पर एक सूचना प्राप्त करते हैं, तो आपके डिस्प्ले के ऊपरी दाहिने कोने पर एक बैनर दिखाई देता है, वहां 25 सेकंड तक रहता है, और फ

  1. IE 8 में 11 के माध्यम से दृश्य स्रोत कोड संपादक बदलें

    कभी इंटरनेट एक्सप्लोरर में किसी वेबपेज के लिए सोर्स कोड देखें? इंटरनेट पर आपके द्वारा देखा जाने वाला प्रत्येक वेबपेज वास्तव में HTML, CSS, Javascript और अन्य जैसी विभिन्न भाषाओं में लिखा गया कोड है। ये सभी तत्व एक वेबपेज बनाने के लिए गठबंधन करते हैं जिसे आप देख और इंटरैक्ट कर सकते हैं। डिफ़ॉल्ट रूप