2009-11-10 22 views
13

क्लास ए और बी बनाम एक आधार वर्ग के साथ पुनर्रचना ActiveRecord मॉडल समान हैं:एक आधार मॉड्यूल

class A < ActiveRecord::Base 
def foo 
    puts "foo" 
end 
end 

class B < ActiveRecord::Base 
def foo 
    puts "foo" 
end 
end 

क्या एक आधार वर्ग के साथ इस तरह पुनर्रचना के बीच का अंतर है:

class Base < ActiveRecord::Base 
def foo 
    puts "foo" 
end 
end 

class A < Base 
end 

class B < Base 
end 

बनाम इस तरह बेस मॉड्यूल:

module Base 
def foo 
    puts "foo" 
end 
end 

class A < ActiveRecord::Base 
include Base 
end 

class B < ActiveRecord::Base 
include Base 
end 
का उपयोग करके 210

एक तरफ से बेहतर तरीका है?

+0

क्या आप बेस क्लास उदाहरण में उप-वर्गों में foo की परिभाषा को शामिल करना चाहते थे? –

+0

नहीं मैंने नहीं किया। धन्यवाद। मैंने इसे हटा दिया। –

उत्तर

24

वहाँ उन दो तरीकों कि सभी अन्य उत्तर याद कर रहे हैं के बीच एक मौलिक अंतर है, और कहा कि एसटीआई से रेलों 'कार्यान्वयन (सिंगल टेबल विरासत) है:

http://api.rubyonrails.org/classes/ActiveRecord/Base.html ("एकल टेबल विरासत" अनुभाग ढूंढें)

मूल रूप से, अगर आप इस तरह अपने बेस वर्ग refactor:

class Base < ActiveRecord::Base 
    def foo 
    puts "foo" 
    end 
end 

class A < Base 
end 

class B < Base 
end 

उसके बाद, आप "ठिकानों" कहा जाता है एक डेटाबेस तालिका के लिए, किसी स्तंभ "प्रकार" कहा जाता है, जो "का मान होना चाहिए साथ अपेक्षा की जाती है एक "या" बी '। इस तालिका के कॉलम आपके सभी मॉडलों में समान होंगे, और यदि आपके पास एक स्तंभ है जो केवल मॉडल में से एक है, तो आपके "बेस" तालिका को denormalized किया जाएगा।

जबकि, अगर आप इस तरह अपने बेस वर्ग refactor:

Module Base 
    def foo 
    puts "foo" 
end 
end 

class A < ActiveRecord::Base 
include Base 
end 

class B < ActiveRecord::Base 
include Base 
end 

तो फिर वहाँ कोई तालिका "ठिकानों" हो जाएगा। इसके बजाए, एक टेबल "एएस" और एक टेबल "बीएस" होगी। यदि उनके पास समान गुण हैं, तो स्तंभों को दोनों तालिकाओं में डुप्लिकेट करना होगा, लेकिन यदि अंतर हैं, तो उन्हें denomarlized नहीं किया जाएगा।

तो, यदि कोई दूसरे पर बेहतर है, हाँ, लेकिन यह आपके आवेदन के लिए विशिष्ट है। अंगूठे के नियम के रूप में, यदि उनके पास समान गुण या बड़े ओवरलैप हैं, तो एसटीआई (पहला उदाहरण) का उपयोग करें, अन्यथा, मॉड्यूल का उपयोग करें (दूसरा उदाहरण)।

+0

मुझे इस उदाहरण के साथ टकराया गया, "मॉड्यूल" होना चाहिए "मॉड्यूल" – Rtype

5

इन तरीकों में से दोनों काम करेंगे। मॉड्यूल या कक्षा का उपयोग करने का निर्णय लेने पर, मेरे पास सवाल यह है कि कक्षा ऑब्जेक्ट पदानुक्रम में फिट होती है, या ये केवल वे विधियां हैं जिनका मैं पुन: उपयोग करना चाहता हूं। अगर मैं सिर्फ DRY कारणों के लिए सामान्य कोड को कारक बनाने की कोशिश कर रहा हूं, जो कि मॉड्यूल की तरह लगता है। यदि वास्तव में एक वर्ग है जो पदानुक्रम में फिट बैठता है जो स्वयं को समझ में आता है, तो मैं एक वर्ग का उपयोग करता हूं।

एक जावा पृष्ठभूमि से आ रहा है, यह मैं ताज़ा कर सकते हैं ये निर्णय लेने के लिए चुनते हैं।

+0

वास्तव में अच्छा, संक्षिप्त स्पष्टीकरण। – ifightcrime

1

मॉड्यूल आपको उसमें अधिक लचीलापन देता है 1) आप केवल एक वर्ग से प्राप्त कर सकते हैं, लेकिन आप कई मॉड्यूल शामिल कर सकते हैं, और 2) आप अपने सुपरक्लास को विरासत में प्राप्त किए बिना बेस क्लास से प्राप्त नहीं कर सकते हैं, लेकिन आप शामिल कर सकते हैं एक मॉड्यूल स्वयं ही (उदाहरण के लिए आप "foo" विधि को किसी अन्य वर्ग में जोड़ना चाहते हैं जो एक सक्रिय रिकॉर्ड मॉडल नहीं है)।

एक और अंतर यह है कि वर्ग बेस में तरीकों के भीतर आप ActiveRecord :: बेस से बातें कह सकते हैं, लेकिन आप नहीं कर सका मॉड्यूल से है।

1

यह क्या तुम सच में ऐसा करने की कोशिश कर रहे हैं पर निर्भर करता है।

  1. अधिभावी या ActiveRecord करने के तरीकों :: बेस जोड़ने: यदि आप respond_tofoo के लिए अपने app में हर ActiveRecord मॉडल चाहते हैं ऐसा करें।
  2. सबक्लास एक्टिव रिकार्ड :: बेस, और प्रत्येक मॉडल को आपके उप-वर्ग से प्राप्त होता है: 1 के समान होता है, लेकिन आपके ऐप के प्रत्येक मॉडल को अपरंपरागत वर्ग का विस्तार करने की आवश्यकता होती है, तो परेशानी के माध्यम से क्यों जाएं।
  3. मॉड्यूल में शामिल हैं: यह अच्छा काम करता है केवल मॉडलों के कुछ नंबर foo के लिए उपयोग की आवश्यकता है। यह बहुत कुछ है जो acts_as_<whatever> प्लगइन्स करते हैं।

नीचे की रेखा, यदि आप चाहते हैं कि प्रत्येक मॉडल के पास एक अलग व्यवहार हो, जो ActiveRecord :: बेस पहले से ही प्रदान करता है, विकल्प 1 का उपयोग करें। यदि आपके मॉडल के केवल कुछ मुट्ठी भर के लिए आवश्यक है, तो मॉड्यूल बनाएं और इसे शामिल करें अपने मॉडल में (विकल्प 3)।

4

आपके पास मॉड्यूल के साथ अधिक लचीलापन है। मॉड्यूल का इरादा विभिन्न प्रकार के वर्गों में फैलाना है। दूसरी विधि के साथ आप खुद को बेस में लॉक कर रहे हैं। इसके अलावा, इसमें कोई फर्क नहीं पड़ता है।

एकाधिक वंशानुक्रम के लिए रूबी के जवाब mixins है। चूंकि आपकी कक्षा पहले ही रेल विशिष्ट वर्गों से विरासत में है, इसलिए वे अब आपके कस्टम वर्गों से प्राप्त नहीं हो सकते हैं।

तो आपकी पसंद एक लंबी श्रृंखला में एक साथ श्रृंखला है, या एक मिश्रण का उपयोग करें जो बहुत साफ है, और समझने में आसान है।

संबंधित मुद्दे