आज आप स्टेट मशीनों के बारे में जानेंगे कि वे कैसे काम करती हैं और AASM रत्न के साथ अपने रूबी प्रोजेक्ट्स में उनका उपयोग कैसे करें।
अब :
ट्रैफिक लाइट की कल्पना करें…
यह लाल, हरा या पीला हो सकता है।
जब यह रंग बदलता है, तो अगला रंग वर्तमान . पर आधारित है एक।
मान लें कि यह एक ऐसा प्रकार है जो अंधे लोगों के लिए आवाज करता है ताकि वे जान सकें कि वे कब पार कर सकते हैं।
अब :
आप इस चीज़ के लिए सॉफ़्टवेयर लिख रहे हैं।
आप कैसे जानेंगे कि हर बार कौन सी ध्वनि बजानी है और आगे कौन सा रंग होना चाहिए?
अगर आप कुछ इस तरह के बयान लिख सकते हैं:
if @light.state == "green" @light.play_green_sound end if @light.state == "green" @light.change_to_yellow end # ...
यह स्टेट चेकिंग कोड हर जगह होगा!
हम इसे कैसे सुधार सकते हैं?
यदि आप ऑब्जेक्ट-ओरिएंटेड डिज़ाइन सिद्धांतों को लागू करते हैं तो आप राज्य डिज़ाइन पैटर्न को फिर से खोज लेंगे।
राज्य डिजाइन पैटर्न क्या है?
स्टेट डिज़ाइन पैटर्न स्टेट मशीन को लागू करने का एक तरीका है।
आपको 3 घटकों की आवश्यकता होगी :
- एक
Context
वर्ग, यह वर्ग जानता है कि वर्तमान स्थिति क्या है - एक
State
वर्ग, यह वर्ग उन विधियों को परिभाषित करता है जिन्हें अलग-अलग राज्यों द्वारा लागू किया जाना चाहिए - हर राज्य के लिए एक वर्ग। ये वर्ग
State
. से इनहेरिट करेंगे कक्षा
हमारे ट्रैफिक लाइट उदाहरण में, संदर्भ TrafficLight
. है स्वयं।
और राज्य हैं Green
, Red
&Yellow
।
हर राज्य को पता होगा कि क्या करना है।
बड़ा लाभ ?
प्रत्येक राज्य स्वयं को जानता है इसलिए वर्तमान स्थिति की जांच करने की कोई आवश्यकता नहीं है। यह कम सशर्त बयानों में तब्दील हो जाता है जो अक्सर जटिलता का स्रोत होते हैं।
ट्रैफिक लाइट कार्यान्वयन
आइए इस पैटर्न के वास्तविक कार्यान्वयन के लिए कोड देखें।
यह रहा TrafficLight
:
class TrafficLight def initialize @state = nil end def next_state(klass = Green) @state = klass.new(self) @state.beep @state.start_timer end end
ये है आधार State
:
class State def initialize(light) @light = light end def beep end def next_state end def start_timer end end
हां, ये 3 तरीके खाली हैं।
इस "इंटरफ़ेस" को परिभाषित करने के लिए अन्य प्रोग्रामिंग भाषाओं (जैसे जावा) में यह एक आम परंपरा है, लेकिन यह रूबी में लोकप्रिय नहीं है।
यह यहाँ प्रदर्शन के उद्देश्य से है।
हालांकि, हम अभी भी initialize
. साझा करना चाहते हैं सभी राज्यों के बीच विधि क्योंकि उन सभी को संदर्भ . की आवश्यकता है (TrafficLight
ऑब्जेक्ट) राज्य परिवर्तन . का संकेत देने के लिए ।
अब :
3 राज्य एक-दूसरे से बहुत मिलते-जुलते हैं, इसलिए मैं आपको उनमें से केवल एक के लिए कोड दिखाने जा रहा हूं।
ये रहा Green
राज्य:
class Green < State def beep puts "Color is now green" end def next_state @light.next_state(Yellow) end def start_timer sleep 5; next_state end end
हर राज्य जानता है कि कैसे और कब दूसरे राज्य में जाना है।
AI गेम उदाहरण
आप वर्तमान स्थिति पर निर्भर गेम को हल करने के लिए एक स्टेट मशीन का उपयोग कर सकते हैं, जैसे कि RubyWarrior।
RubyWarrior में आपको एक प्लेयर ऑब्जेक्ट और एक बोर्ड दिया जाता है।
लक्ष्य हैं :
- बोर्ड के सभी दुश्मनों को हराएं
- अपने HP को 0 से ऊपर रखते हुए बाहर निकलें
आप एक बार में एक चाल चल सकते हैं और यदि आप स्तर को पूरा करना चाहते हैं तो आपको एक अच्छा चुनाव करना होगा।
वर्तमान स्थिति को देखते हुए आपको यह चुनाव करने में मदद मिलती है।
इसलिए स्टेट मशीन एक अच्छा समाधान है।
यहां एक उदाहरण दिया गया है :
class Attacking < State def play(warrior) warrior.attack! @player.set_state(Healing) unless enemy_found?(warrior) end end
यह उन राज्यों में से एक है जिसमें हमारा योद्धा हो सकता है, जब हमारे पास कोई दुश्मन नहीं होता है तो हम Healing
में चले जाते हैं युद्ध के नुकसान से उबरने के लिए राज्य।
AASM रत्न का उपयोग करना
यदि आप यह सुनिश्चित करते हुए वर्तमान स्थिति पर नज़र रखना चाहते हैं कि ट्रांज़िशन मान्य हैं तो आप AASM जैसे स्टेट मशीन रत्न का उपयोग कर सकते हैं।
यह रत्न घटनाओं . के विचार के इर्द-गिर्द बनाया गया है (जैसे कोई लाइट स्विच दबाना) जो अन्य राज्यों में संक्रमण को ट्रिगर करता है।
यहां एक उदाहरण दिया गया है :
require 'aasm' class Light include AASM aasm do state :on, :off event :switch do transitions :from => :on, :to => :off, :if => :on? transitions :from => :off, :to => :on, :if => :off? end end end
इस वर्ग का उपयोग कैसे करें :
light = Light.new p light.on? # true light.switch p light.on? # false
इस राज्य मशीन का उपयोग करके आप केवल "चालू" स्थिति में संक्रमण कर सकते हैं यदि वर्तमान स्थिति "बंद" है। राज्य संक्रमण के दौरान विशिष्ट कोड चलाने के लिए आपके पास कई कॉलबैक (पहले/बाद) भी हो सकते हैं।
ये कॉलबैक इसमें निम्न चीज़ें शामिल हो सकती हैं:
- ईमेल भेजना
- राज्य परिवर्तन लॉगिंग
- लाइव मॉनिटरिंग डैशबोर्ड अपडेट करना
इसके अलावा, AASM के पास ActiveRecord
का उपयोग करके वर्तमान स्थिति को डेटाबेस में सहेजने का विकल्प है ।
AASM जेम वीडियो
सारांश
आपने राज्य मशीनों, राज्य डिजाइन पैटर्न और एएएसएम रत्न के बारे में सीखा है! मेरे रूबी न्यूज़लेटर (7000+ सब्सक्राइबर) की सदस्यता लेकर अभी सीखते रहें ताकि आप नए लेख और ग्राहक-अनन्य रूबी टिप्स से न चूकें ।
अब इन नए विचारों के साथ अभ्यास करने का समय है 🙂
पढ़ने के लिए धन्यवाद!