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

Ruby में अनउपयोग की गई क्लासेस को रोकना: क्लीन ऑब्जेक्ट मॉडलिंग के लिए एक गाइड

चूंकि Ruby एक ऑब्जेक्ट-ओरिएंटेड भाषा है, हम दुनिया को ऑब्जेक्ट्स के एक सेट के रूप में मॉडल करते हैं। हम कहते हैं कि दो इंटीजर्स (x और y) एक पॉइंट हैं, और एक लाइन में उनमें से दो हैं।

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

जब आपको एक सेल की आवश्यकता होती है तो क्या होता है? खैर, पॉइंट डेटा का मालिक है। तो आप पॉइंट में अपने सेल मेथड्स जोड़ते हैं। समय के साथ आप एक पॉइंट क्लास के साथ समाप्त होते हैं जो ढीले से संबंधित मेथड्स का एक जंक ड्रॉअर है।

जंक-ड्रॉअर क्लासेस इतनी आम हैं कि हम अक्सर उन्हें अपरिहार्य मान लेते हैं और डेवलपमेंट में एक "रीफैक्टरिंग" चरण जोड़ देते हैं। लेकिन क्या होगा अगर हम पहली जगह में समस्या से बच सकते हैं?

वेब डेवलपमेंट का पहला नियम यह है कि हम यूजर क्लास के बारे में बात नहीं करते

किसी भी बैटल-हार्डेंड प्रोडक्शन Rails ऐप के दिल में User नामक एक विशाल राक्षस क्लास होती है।

यह हमेशा मासूमियत से शुरू होता है। आप लोगों को लॉग इन करने देना चाहते हैं। आपको उनका यूज़रनेम और पासवर्ड स्टोर करने की आवश्यकता है, तो आप एक क्लास बनाते हैं:

class User
  attr_accessor :username, :password, :email, :address
  def authenticate!(password)
    ...
  end
end

यह इतना अच्छा काम करता है कि अंततः लोग आपको पैसा देना चाहते हैं। "ठीक है," हम कहते हैं "एक यूज़र मूल रूप से एक सब्सक्राइबर के समान ही चीज़ है तो हम बस कुछ विशेषताएं और कुछ मेथड्स जोड़ देंगे।"

class User
  ...
  attr_accessor :payment_processor_token, :subscription_plan_id, ...etc
  def charge_cc
    ...
  end
end

शानदार! अब हम कुछ वास्तविक पैसा कमा रहे हैं! CEO ने फैसला किया है कि वे यूज़र्स की संपर्क जानकारी के साथ VCards निर्यात करने में सक्षम होना चाहते हैं ताकि सेल्स टीम उन्हें आसानी से SalesForce में आयात कर सके। vim को फायर करने का समय:

class User
  ...
  def export_vcard
    ...
  end
end

हमने क्या किया?

हम एक User क्लास के साथ शुरू हुए, जिसका एकमात्र उद्देश्य ऑथेंटिकेशन को संभालना था। अतिरिक्त मेथड्स और विशेषताओं को जोड़कर, हमने इसे User/Subscriber/Contact फ्रेंकस्टीन हाइब्रिड में बदल दिया।

हम ऐसा क्यों करेंगे? क्या हम खुद का सम्मान डेवलपर्स के रूप में नहीं करते? क्या हमारे माता-पिता ने हमें पर्याप्त प्यार नहीं किया? या हमने खुद को विफलता के लिए स्थापित किया यह मानकर कि यह डेटा वास्तव में एक चीज़ है, एक ऑब्जेक्ट?

हम क्यों कहते हैं कि यूज़रनेम, पासवर्ड और ईमेल एड्रेस का कॉम्बो एक यूज़र है? क्यों नहीं एक सब्सक्राइबर? या एक संपर्क? या एक सेशनहोल्डर?

डेटा के बारे में सच्चाई यह है कि यह डेटा है

डेटा सिर्फ डेटा है। आज आपको इसे प्रेमी की तरह व्यवहार करने की आवश्यकता हो सकती है। कल यह पूर्व-प्रेमी हो सकता है।

यह वह दृष्टिकोण है जो Elixir जैसी फंक्शनल भाषाएं लेती हैं। डेटा को सरल संरचनाओं में संग्रहीत किया जाता है जैसे Ruby के हैश, ऐरे, स्ट्रिंग्स, आदि। जब आप डेटा के साथ कुछ करना चाहते हैं तो आप इसे एक फंक्शन में पास करते हैं। कोई भी परिणाम उस फंक्शन से लौटाए जाते हैं।

यह सरल लगता है, लेकिन यह दृष्टिकोण विभिन्न मॉड्यूल्स में चिंताओं को अलग करना बहुत आसान बनाता है।

यहाँ एक कार्टून है कि हम Elixir में अपना User सिस्टम कैसे बना सकते हैं:

my_user = %{username: "foo", password: ..., phone: ..., payment_token: ...}
my_user = Authentication.authenticate(my_user)
my_user = Subscription.charge(my_user)
my_user = Contact.export_vcard(my_user)

क्योंकि डेटा कोड से अलग है, कोई मॉड्यूल उस डेटा की विशेषाधिकार प्राप्त व्याख्या नहीं रखता।

इसे Ruby पर वापस लाना

चूंकि यह दृष्टिकोण Elixir में इतना अच्छा काम करता है, तो इसे Ruby में क्यों न अपनाएं? हमें User को इसके डेटा के लिए एक सिंपल रैपर बनाने और सभी बिजनेस लॉजिक को मॉड्यूल्स में खींचने से कुछ भी नहीं रोकता।

class User
  attr_accessor :username, :password, :email, :address
end

module Authentication
  def self.authenticate!(user)
    ..
  end
end

module Subscription
  def self.charge(user)
    ..
  end
end

module Contact
  def self.export_vcard(user)
    ..
  end
end

आप User क्लास को एक स्ट्रक्ट में भी बदल सकते हैं, या इसे (किंडा) अपरिवर्तनीय बनाने के लिए कोड जोड़ सकते हैं।

तो क्या?

क्या यह एक तुच्छ परिवर्तन लगता है? क्या बात है?

जैसा कि हमने देखा है, विशिष्ट OO दृष्टिकोण की समस्याएं हैं जैसे-जैसे यह पुराना होता है। यह कहकर कि एक निश्चित क्लास मालिक है डेटा, हम समस्याओं में पड़ जाते हैं जब हमें उस डेटा को किसी अन्य तरीके से उपयोग करने की आवश्यकता होती है।

मॉड्यूलर दृष्टिकोण में, हालांकि, व्यवहार जोड़ना कोई समस्या नहीं है। हम बस एक नया मॉड्यूल बनाते हैं जो डेटा की व्याख्या करता है जिस भी तरीके से उसे आवश्यकता होती है। यह करना आसान है क्योंकि डेटा और कार्यक्षमता पूरी तरह से अलग हैं।

अन्य दृष्टिकोण

जंक-ड्रॉअर समस्या को रोकने के अन्य दृष्टिकोण हैं। पारंपरिक रूप से, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में आप इनहेरिटेंस और सावधानीपूर्वक रीफैक्टरिंग के माध्यम से ऐसा करने का प्रयास करेंगे। 2012 में सैंडी मेट्ज़ ने Practical Object Oriented Design in Ruby प्रकाशित किया जिसने कई लोगों को डिपेंडेंसी इंजेक्शन का उपयोग करके ऑब्जेक्ट्स को कंपोज करना शुरू करने के लिए आश्वस्त किया। हाल ही में, फंक्शनल प्रोग्रामिंग की लोकप्रियता ने Rubyists को अपरिवर्तनीय "डेटा ऑब्जेक्ट्स" के साथ प्रयोग करने के लिए प्रेरित किया है।

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

मुझे संदेह है कि इन दृष्टिकोणों को जंक-ड्रॉअर समस्या से बचने में जो भी सफलता मिलती है, वह डेटा को कोड से डिकॉपल करने का परिणाम है।

  1. रूबी एक्सेप्शन को प्रासंगिक डेटा के साथ बढ़ाएं – एक व्यावहारिक गाइड रूबी एक्सेप्शन को प्रासंगिक डेटा के साथ बढ़ाएं – एक व्यावहारिक गाइड

    कभी-कभी मानक बैकट्रेस/एरर मैसेज कॉम्बो पर्याप्त नहीं होता। कभी-कभी आपको एरर के कारण का पता लगाने के लिए अतिरिक्त डेटा की आवश्यकता होती है। सौभाग्य से, रूबी में यह करना बेहद आसान है। एरर मैसेज कस्टमाइज़ करना अपने एरर में प्रासंगिक जानकारी जोड़ने का सबसे सरल तरीका है उसे एक्सेप्शन के मैसेज में शामिल क

  1. Ruby डेवलपर्स के लिए आवश्यक डेटा स्ट्रक्चर्स: एक व्यावहारिक गाइड Ruby डेवलपर्स के लिए आवश्यक डेटा स्ट्रक्चर्स: एक व्यावहारिक गाइड

    Arrays को समझना जब आप प्रोग्रामिंग के बारे में पढ़ना शुरू करते हैं तो एरे पहला डेटा स्ट्रक्चर है जिसके बारे में आप सीखते हैं। एरे मेमोरी के एक सन्निहित हिस्से का उपयोग करते हैं जहां ऑब्जेक्ट्स एक के बाद एक बिना अंतराल के संग्रहीत होते हैं। C जैसी निचले स्तर की प्रोग्रामिंग भाषाओं के विपरीत, Ruby आपक

  1. Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण

    Ruby का एक नया संस्करण नई सुविधाओं और प्रदर्शन सुधारों के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज (Endless Ranges) Ruby 2.5 और पुराने संस्करण पहले से ही अंतहीन रेंज का एक रूप (Float::INFINITY के साथ) का समर्थन करते हैं, लेकिन Ruby 2.6 इसे अगले स्त