क्या आप OOP (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) की पूरी शक्ति का उपयोग कर रहे हैं या आप चूक रहे हैं?
यदि आप किसी वस्तु के प्रकार के आधार पर निर्णय ले रहे हैं तो आप एक महत्वपूर्ण OOP विशेषता को याद कर रहे हैं:बहुरूपता।
प्रकार के निर्णय आमतौर पर केस स्टेटमेंट के अंदर किए जाते हैं (जो OO के अनुकूल नहीं होते हैं) और इस लेख में आप सीखेंगे कि उन्हें हटाकर बेहतर कोड कैसे लिखना है।
प्रकारों की जांच कर रहा है
मैं आपको एक उदाहरण दिखाकर शुरू करता हूं जहां हम बहुरूपता का लाभ नहीं उठाते हैं।
हम "रॉक, पेपर, कैंची" गेम को लागू करना चाहते हैं और हमने एक Game का फैसला किया है हर संभव कदम के लिए कक्षा और एक वर्ग।
एक विजेता की जांच करने के लिए हम एक play . लागू करने जा रहे हैं Game पर विधि :
class Game
def self.play(move1, move2)
return :tie if move1 == move2
move1.wins_against?(move2)
end
end
और यहाँ एक चाल है (अन्य समान पैटर्न का अनुसरण करते हैं):
class Rock
def wins_against?(other_move)
case other_move
when Paper then false
when Scissors then true
end
end
end
अब हम play . को कॉल कर सकते हैं दो चालों के साथ विधि और हमें पता चल जाएगा कि पहली चाल जीत जाती है या नहीं।
p Game.play(Rock.new, Paper.new) # false
ठीक है, यह काम कर रहा है, लेकिन क्या हम बेहतर कर सकते हैं? क्या हम उस बदसूरत केस स्टेटमेंट से छुटकारा पा सकते हैं?
टाइप चेकिंग के बजाय बहुरूपता
हाँ! हम OOP बुनियादी बातों का उपयोग करके टाइप-चेकिंग केस स्टेटमेंट से छुटकारा पा सकते हैं।
विचार इस तथ्य का उपयोग करना है कि हम वर्तमान वर्ग को अन्य आंदोलन वस्तु से पूछने के लिए जानते हैं कि क्या वह हमें हरा सकती है।
और हम एक विधि नाम का उपयोग करने जा रहे हैं जो हमारी कक्षा के लिए विशिष्ट है (Rock . के लिए) विधि का नाम हो सकता है:do_you_beat_rock? )
रूबी में, बहुरूपता ऑब्जेक्ट की कक्षा की जांच किए बिना किसी भी ऑब्जेक्ट को किसी भी विधि कॉल (जिसे संदेश के रूप में भी जाना जाता है, OOP भाषा में) भेजने की क्षमता है। इसे "बतख टाइपिंग" के रूप में भी जाना जाता है, लेकिन मुझे वह शब्द पसंद नहीं है 🙂
जावा में (एक सेकंड के लिए मेरे साथ रहें ...), आपके पास "इंटरफ़ेस" नामक कुछ है जो आपको कंपाइलर स्तर पर एक वर्ग द्वारा लागू किए जाने वाले तरीकों के एक सेट को मजबूर करने की अनुमति देता है।
हमारे पास रूबी (शायद बेहतर के लिए) में नहीं है, इसलिए आपको परीक्षण पर निर्भर रहना होगा।
आइए एक कोड उदाहरण देखें कि यह नया कार्यान्वयन कैसा दिखता है:
class Rock
def wins_against?(other_move)
other_move.do_you_beat_rock?
end
def do_you_beat_paper?
false
end
def do_you_beat_scissors?
true
end
end
ध्यान दें कि केस स्टेटमेंट कैसे चला गया है। इसे एकल विधि कॉल और दो विधि परिभाषाओं से बदल दिया गया है।
<ब्लॉकक्वॉट>
अपडेट करें :जैसा कि कुछ पाठकों ने टिप्पणी की है, मैंने यह नहीं देखा कि इस पैटर्न को लागू करते समय तर्क उलट जाता है। डेनियल पी. क्लार्क द्वारा प्रस्तावित समाधान केवल play . में क्रम को फ़्लिप करना है move2.wins_against?(move1) . की विधि ।
क्या यह बहुत साफ नहीं है? आपको क्या लगता है?
एक और चाल!
अब मान लीजिए कि आप एक नई चाल जोड़ना चाहते हैं। आपको क्या बदलना होगा?
एक मिनट इसके बारे में सोचें...
केस स्टेटमेंट दृष्टिकोण के साथ आपको हर कदम पर एक नई शाखा जोड़नी होगी। ध्यान दें कि नई कार्यक्षमता शुरू करने के लिए आपको पूरी तरह से काम करने के तरीके को बदलने के लिए "मजबूर" किया जाता है।
लेकिन यह हमारे अधिक OOP उन्मुख संस्करण के साथ कोई समस्या नहीं है। हमें बस इतना करना है कि नए तरीके जोड़ें। यह खुला/बंद सिद्धांत (सॉलिड में "O") क्रिया में है।
एक अन्य विकल्प मेटाप्रोग्रामिंग का उपयोग करना हो सकता है (method_missing . के साथ) या define_method )।
क्या मैं वास्तव में इसके लिए मेटाप्रोग्रामिंग का उपयोग करूंगा?
शायद नहीं, जब तक कि चालों की संख्या में लगातार परिवर्तन न हो, या बड़ी संख्या में चालें न हों।
मेटाप्रोग्रामिंग की लागत होती है, यह चांदी की गोली नहीं है जैसा कि कुछ लोग मान सकते हैं। आप थोड़े अतिरिक्त लचीलेपन के लिए प्रदर्शन और पठनीयता का व्यापार करेंगे।
निष्कर्ष
इस लेख में आपने सीखा कि आपको कक्षा के प्रकारों की जांच के लिए केस स्टेटमेंट का उपयोग करने से बचना चाहिए . इसके बजाय, आपको बहुरूपता का लाभ उठाना चाहिए ।
यह आपको बेहतर कोड बनाने में मदद करेगा जिसे मौजूदा कोड को बदलने के बजाय नया कोड जोड़कर बढ़ाया जा सकता है। अब कार्रवाई करने और कुछ रिफैक्टरिंग करने की आपकी बारी है 🙂
बीटीडब्ल्यू इसका मतलब यह नहीं है कि मैं आपके टूलबॉक्स से केस स्टेटमेंट से पूरी तरह छुटकारा पाने की वकालत कर रहा हूं, लेकिन जब भी आप खुद को एक लिखते हुए पाते हैं तो आपको सावधान रहना चाहिए। सुनिश्चित करें कि यह समस्या का सबसे अच्छा समाधान है।
इस लेख को साझा करना न भूलें अगर आप चाहते हैं कि मैं इस तरह के लेख लिखता रहूं!