आज आप स्टेट मशीन्स के बारे में सीखेंगे, वे कैसे काम करते हैं और AASM जेम के साथ अपने रूबी प्रोजेक्ट्स में उनका उपयोग कैसे करें।
अब:
एक ट्रैफिक लाइट की कल्पना करें...
यह लाल, हरा या पीला हो सकता है।
जब यह रंग बदलता है, तो अगला रंग वर्तमान पर आधारित होता है।

मान लें कि यह वह प्रकार है जो नेत्रहीन लोगों के लिए ध्वनि बजाता है ताकि वे जान सकें कि वे कब पार कर सकते हैं।
अब:
आप इस चीज़ के लिए सॉफ्टवेयर लिख रहे हैं।
आप कैसे जानेंगे कि हर बार कौन सी ध्वनि बजानी है और अगला रंग क्या होना चाहिए?
आप कुछ if स्टेटमेंट्स लिख सकते हैं जैसे:
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 मेथड्स खाली हैं।
अन्य प्रोग्रामिंग भाषाओं (जैसे Java) में इस "इंटरफेस" को परिभाषित करना एक सामान्य कन्वेंशन है, लेकिन यह रूबी में लोकप्रिय नहीं है।
यह प्रदर्शन उद्देश्यों के लिए यहाँ है।
हालांकि, हम अभी भी सभी स्टेट्स के बीच 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
इस स्टेट मशीन का उपयोग करके आप केवल "on" स्टेट में ट्रांजिशन कर सकते हैं यदि वर्तमान स्टेट "off" है। आप स्टेट ट्रांजिशन्स के दौरान चलाने के लिए विशिष्ट कोड चलाने के लिए कई कॉलबैक्स (पहले/बाद) भी रख सकते हैं।
ये कॉलबैक्स शामिल हो सकते हैं:
- ईमेल भेजना
- स्टेट चेंज लॉगिंग
- लाइव मॉनिटरिंग डैशबोर्ड अपडेट करना
इसके अलावा, AASM में ActiveRecord का उपयोग करके वर्तमान स्टेट को डेटाबेस में सेव करने का विकल्प है।
AASM जेम वीडियो
सारांश
आपने स्टेट मशीन्स, स्टेट डिज़ाइन पैटर्न और AASM जेम के बारे में सीखा! अब मेरे रूबी न्यूज़लेटर (7000+ सब्सक्राइबर्स) को सब्सक्राइब करके सीखते रहें ताकि आप नए लेख और सब्सक्राइबर-एक्सक्लूसिव रूबी टिप्स मिस न करें।
अब इन नए विचारों के साथ अभ्यास करने का समय है 🙂
पढ़ने के लिए धन्यवाद!