डीप रेल्स: एब्सट्रैक्ट क्लासेस का उपयोग कैसे करें

कभी-कभी आपकी यात्रा में, आप एक छोटे वर्ग-स्तर की घोषणा पर आते हैं जो एक वर्ग को सार के रूप में सेट करता है:

कक्षा SomeAbstractModel 

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

पहली चीजें पहले: यह क्या करता है?

सीधे शब्दों में कहें: जब एक मॉडल एक अमूर्त वर्ग के रूप में एक मॉडल बनाता है तो यह एक अंतर्निहित तालिका के बिना ऐसा करता है। इसका मतलब है कि यह मॉडल कभी भी त्वरित नहीं हो सकता है। कभी! किन्हीं भी परिस्थितियों में। ऐसा करने से त्रुटि होती है:

SomeAbstractClass.create!
# => NotImplementedError: (वाहन एक सार वर्ग है और इसे तत्काल नहीं किया जा सकता है।)

एक सार वर्ग उन सभी विधियों के साथ बनाया गया है, जिनके बारे में आप ApplicationRecord - सत्यापनकर्ताओं, दृढ़ता विधियों आदि पर खोजने की अपेक्षा करते हैं, लेकिन एक अमूर्त वर्ग का उदाहरण कभी भी अपने आप मौजूद नहीं हो सकता है।

तो फिर क्यों परेशान उन्हें का उपयोग कर?

रेल में सिंगल-टेबल इनहेरिटेंस (एसटीआई) प्रसिद्ध समस्याग्रस्त है, और अमूर्त वर्ग - जब उचित तरीके से मिटा दिया जाता है - एसटीआई के लक्षणों में से एक के लिए एक समाधान प्रदान करता है जिससे डेवलपर्स सबसे अधिक निराश होते हैं।

इतने सारे खाली कॉलम: एसटीआई समस्या

जब आप रूबी में एक हेरिटेज मॉडल बनाते हैं, तो एसटीआई तय करता है कि उस मॉडल में एक: टाइप कॉलम है। वह कॉलम (जैसा कि अपेक्षित है) ऑब्जेक्ट के प्रकार को संग्रहीत करता है। एसटीआई यह भी तय करता है कि इस अभिभावक मॉडल में किसी भी और हर कॉलम के लिए कॉलम हैं जो एक बच्चे के रिकॉर्ड की आवश्यकता हो सकती है।

उदाहरण के लिए, वाहन नामक एक वर्ग पर विचार करें:

वर्ग वाहन 
कन्वर्ट कन्वर्ट_वेट (यूनिट)
    मामला इकाई
    जब: एलबीएस
      वजन * 2.20462
    जब: जी
      वजन * 1000.0
    समाप्त
  समाप्त
समाप्त

और वाहन के दो बच्चे:

क्लास कार <वाहन
  मान्य: नंबर_ऑफ़_व्हील्स, उपस्थिति: सच, अनुमति_बल: झूठी
समाप्त
कक्षा हवाई जहाज <वाहन
  मान्य: नंबर_ऑफ़_विंग्स, उपस्थिति: सच, अनुमति_ब्लैंक: गलत
समाप्त

STI प्रतिमान के भीतर, वाहन के लिए माइग्रेशन एक तालिका बनाएगा: जिसमें एक प्रकार का कॉलम हो। यदि बनाई गई वस्तु एक कार है, तो प्रकार "कार" होगा। यदि बनाई गई वस्तु एक हवाई जहाज है, तो प्रकार "हवाई जहाज" होगा। यह सब अच्छा और अच्छा है।

लेकिन वाहनों की तालिका को भी: number_of_wheels कॉलम और a: number_of_wings कॉलम की आवश्यकता होगी, क्योंकि उन विशेषताओं को उसके कुछ बच्चे रिकॉर्ड द्वारा आवश्यक हैं:

create_table: वाहन करते हैं | t |
  # कुछ बच्चों के लिए आवश्यक कॉलम
  t.integer: number_of_wheels
  t.integer: number_of_wings
  # सभी बच्चों के लिए आवश्यक कॉलम
  with_options अशक्त: गलत करते हैं
    t.string: उत्तराधिकार के लिए # टाइप करना आवश्यक है
    t.integer: वजन
    t.string: रंग
  समाप्त
समाप्त

अब इस धागे को उतारने के लिए एक सेकंड लें: जैसा कि हम इन मॉडलों के व्यवहार के बारे में अधिक योजना बनाते हैं, हम महसूस करेंगे कि एक कार और एक हवाई जहाज बहुत अलग वाहन हैं। वे जो विशेषताएँ साझा नहीं करते हैं वे सैकड़ों में संख्या हो सकती है। इस साझा तालिका पर बहुत सारे कॉलम हैं जो खाली बैठेंगे।

और जब हम नाव, स्नोमोबाइल, और टोबोगन बनाते हैं तो क्या होता है? ऐसा लगता है जैसे हम एक बड़ी, फूला हुई मेज के लिए नेतृत्व कर रहे हैं। यह डेवलपर्स की सबसे गहरी शिकायतों में से एक है, जो रेल की विरासत तंत्र के साथ सबसे गहरी शिकायत है।

बचाव के लिए सार कक्षाएं!

सार कक्षाएं किसी चीज के लिए अनुमति देती हैं जो रेल में एक सच्ची इंटरफ़ेस ऑब्जेक्ट जैसा दिखता है: मॉडल अपने सभी बच्चों के लिए सामान्य व्यवहार रखता है, लेकिन - क्योंकि इसका कोई डेटा प्रतिनिधित्व नहीं है - यह (और कुछ भी नहीं जानता) अपने बच्चों द्वारा आवश्यक डेटा रखता है। ।

हमारे वर्ग के वाहन को एक सार वर्ग के रूप में पुनर्विचार करने दें:

वर्ग वाहन 
with_options उपस्थिति: सत्य, allow_blank: false करना
    मान्य: वजन
    मान्य: रंग
  समाप्त
कन्वर्ट कन्वर्ट_वेट (यूनिट)
    मामला इकाई
    जब: एलबीएस
      वजन * 2.20462
    जब: जी
      वजन * 1000.0
    समाप्त
  समाप्त
समाप्त

और वाहन के लिए प्रवास:

* * चिरप * * चिरप *

उसे ले लो? कोई डेटा प्रतिनिधित्व नहीं है जो भी हो। डेटा प्रतिनिधित्व पूरी तरह से उन वर्गों द्वारा परिभाषित किया गया है जो वाहन से प्राप्त होते हैं:

वर्ग CreateVehicles 
    create_table: हवाई जहाज करते हैं | t |
      with_options अशक्त: गलत करते हैं
        t.integer: वजन
        t.string: रंग
        t.integer: number_of_wings
      समाप्त
    समाप्त
  समाप्त
समाप्त

दोनों तालिकाओं में, हम हर कॉलम पर 100% उपयोग देखने की उम्मीद करते हैं। हमारे पास उन वस्तुओं के लिए विशेष टेबल हैं, जिनका वे प्रतिनिधित्व करते हैं, लेकिन फिर भी हमारे व्यवहार को मॉडल में साझा करने के लिए मिलता है।

लपेटें: मुझे एब्सट्रैक्ट क्लासेस का उपयोग कब करना चाहिए?

यह एसटीआई, प्रति से बेहतर नहीं है, लेकिन यह कुछ मामलों में बेहतर समाधान हो सकता है, खासकर जब बच्चे के मॉडल में एक दूसरे से बहुत अलग सेट हो सकते हैं।

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

इन तकनीकों को समझने के लिए यह समझना महत्वपूर्ण है कि उनका उपयोग कब और कैसे किया जाना चाहिए। संदर्भ और बाधा एक ढांचे में सब कुछ है जितना कि रेल के रूप में लचीला है। समझें कि आपको क्या चाहिए, फिर उस पैटर्न को चुनें जो आपकी सबसे अच्छी सेवा करेगा।