'स्टेट' एक सामान्य प्रोग्रामिंग शब्द है जिसे सभी डेवलपर्स द्वारा अनुभव किया जाता है क्योंकि वे शुरुआत से मध्यवर्ती स्तर की प्रोग्रामिंग तक आगे बढ़ते हैं। तो, "राज्य" शब्द का वास्तव में क्या अर्थ है?
सामान्य तौर पर, किसी वस्तु की स्थिति वस्तु या उसके एक हिस्से का केवल वर्तमान स्नैपशॉट होती है। इस बीच, कंप्यूटर विज्ञान में, एक प्रोग्राम की स्थिति को पहले से संग्रहीत इनपुट के बारे में उसकी स्थिति के रूप में परिभाषित किया जाता है। इस संदर्भ में, "राज्य" शब्द का प्रयोग उसी तरह किया जाता है जैसे यह विज्ञान में होता है: किसी वस्तु की स्थिति, जैसे कि गैस, तरल या ठोस, इसकी वर्तमान भौतिक प्रकृति और कंप्यूटर प्रोग्राम की स्थिति का प्रतिनिधित्व करती है। इसके वर्तमान मूल्यों या सामग्री को दर्शाता है।
कंप्यूटर प्रोग्राम में स्टोर किए गए इनपुट को वेरिएबल या स्थिरांक के रूप में परिरक्षित किया जाता है। एक कार्यक्रम की स्थिति का आकलन करते समय, डेवलपर्स इन इनपुट में निहित मूल्यों की जांच कर सकते हैं। प्रोग्राम के चलने के दौरान उसकी स्थिति बदल सकती है - चर बदल सकते हैं, और स्मृति मान बदल सकते हैं। एक नियंत्रण चर, जैसे कि एक लूप में उपयोग किया जाता है, उदाहरण के लिए, प्रत्येक पुनरावृत्ति पर कार्यक्रम की स्थिति को बदलता है। किसी प्रोग्राम की वर्तमान स्थिति का परीक्षण कोडबेस का परीक्षण या विश्लेषण करने के लिए किया जा सकता है।
सरल प्रणालियों में, राज्य प्रबंधन को अक्सर इफ-इफ, इफ-थेन-एल्स, ट्राई-कैच स्टेटमेंट्स, या बूलियन फ्लैग्स के साथ नियंत्रित किया जाता है; हालांकि, यह तब बेकार है जब एक कार्यक्रम में बहुत अधिक राज्यों की कल्पना की जा सकती है। वे भद्दे, जटिल कोड को जन्म दे सकते हैं जिन्हें समझना, बनाए रखना और डिबग करना मुश्किल है।
इफ-क्लॉज या बूलियन का एक नुकसान यह है कि वे काफी व्यापक हो सकते हैं, और दूसरे राज्य को जोड़ना मुश्किल है क्योंकि इसके लिए कई अलग-अलग वर्गों के कोड को फिर से लिखना आवश्यक है। मान लें कि आप एक ऐसा गेम बनाना चाहते हैं जिसमें मुख्य मेनू, एक गेम लूप और एक पूर्ण स्क्रीन हो।
आइए उदाहरण के लिए एक वीडियो प्लेयर बनाएं:
class Video: def __init__(self, source): self.source = source self.is_playing = False self.is_paused = False self.is_stopped = True # A video can only be played when paused or stopped def play(self): if not self.is_playing or self.is_paused: # Make the call to play the video self.is_playing = True self.is_paused = False else: raise Exception( 'Cannot play a video that is already playing.' ) # A video can only be paused when it is playing def pause(self): if self.is_playing: # Make the call to pause the video self.is_playing = False self.is_paused = True else: raise Exception( 'Cannot pause a video that is not playing' ) # A video can only be stopped when it is playing or paused def stop(self): if self.is_playing or self.is_paused: # Make the call to stop the video self.is_playing = False self.is_paused = False else: raise Exception( 'Cannot stop a video that is not playing or paused' )
उपरोक्त कोड स्निपेट एक साधारण वीडियो प्लेयर एप्लिकेशन का एक और कार्यान्वयन है, जहां तीन बुनियादी स्थितियां हैं - खेलना, रुकना और रुकना। हालांकि, अगर हम और राज्यों को जोड़ने का प्रयास करते हैं, तो कोड तेजी से जटिल, फूला हुआ, दोहराव और समझने और परीक्षण करने में कठिन हो जाएगा। आइए देखें कि दूसरे राज्य 'रिवाइंड' को जोड़ते समय कोड कैसा दिखता है:
class Video: def __init__(self, source): self.source = source self.is_playing = False self.is_paused = False self.is_rewinding = False self.is_stopped = True # A video can only be played when it is paused or stopped or rewinding def play(self): if self.is_paused or self.is_stopped or self.is_rewinding: # Make the call to play the video self.is_playing = True self.is_paused = False self.is_stopped = False self.is_rewinding = False else: raise Exception( 'Cannot play a video that is already playing.' ) # A video can only be paused when it is playing or rewinding def pause(self): if self.is_playing or self.is_rewinding: # Make the call to pause the video self.is_playing = False self.is_paused = True self.is_rewinding = False self.is_stopped = False else: raise Exception( 'Cannot pause a video that is not playing or rewinding' ) # A video can only be stopped when it is playing or paused or rewinding def stop(self): if self.is_playing or self.is_paused or self.is_rewinding: # Make the call to stop the video self.is_playing = False self.is_paused = False self.is_stopped = True self.is_rewinding = False else: raise Exception( 'Cannot stop a video that is not playing or paused or rewinding' ) # 4. A video can only be rewinded when it is playing or paused. def rewind(self): if self.is_playing or self.is_paused: # Make the call to rewind the video self.is_playing = False self.is_paused = False self.is_stopped = False self.is_rewinding = True else: raise Exception( 'Cannot rewind a video that is not playing or paused' )
राज्य-पैटर्न के बिना, आपको अद्यतन और ड्रा विधियों सहित पूरे कोड में कार्यक्रम की वर्तमान स्थिति की जांच करनी होगी। यदि आप सेटिंग स्क्रीन जैसी चौथी स्थिति जोड़ना चाहते हैं, तो आपको कई अलग-अलग वर्गों के कोड को अपडेट करना होगा, जो असुविधाजनक है। यहीं से राज्य मशीनों का विचार काम आता है।
कंप्यूटर विज्ञान में राज्य मशीनें कोई नई अवधारणा नहीं हैं; वे सॉफ्टवेयर व्यवसाय में उपयोग किए जाने वाले बुनियादी डिजाइन पैटर्न में से एक हैं। यह कोडिंग-ओरिएंटेड की तुलना में अधिक सिस्टम-ओरिएंटेड है और इसका उपयोग उपयोग के मामलों के आसपास के मॉडल के लिए किया जाता है।
आइए उबर के माध्यम से कैब किराए पर लेने का एक सरल वास्तविक जीवन उदाहरण देखें:
स्क्रीन 1 पहली स्क्रीन है जिसे इस उपयोग के मामले में सभी उपयोगकर्ता देखते हैं, और यह स्वयं निहित है। स्क्रीन 2 स्क्रीन 1 पर निर्भर है, और आप स्क्रीन 2 पर तब तक नहीं जा पाएंगे जब तक आप स्क्रीन 1 पर सटीक डेटा नहीं देते। इसी तरह, स्क्रीन 3 स्क्रीन 2 पर निर्भर है, जबकि स्क्रीन 4 स्क्रीन 3 पर निर्भर है। यदि न तो आप न ही आपका ड्राइवर आपकी यात्रा को रद्द करता है, आपको स्क्रीन 4 पर ले जाया जाएगा, जहां आप अपनी वर्तमान यात्रा समाप्त होने तक दूसरी यात्रा की योजना नहीं बना पाएंगे।
मान लीजिए कि बहुत तेज़ बारिश हो रही है और कोई भी ड्राइवर आपकी यात्रा को स्वीकार नहीं करता है या आपके क्षेत्र में कोई उपलब्ध ड्राइवर आपकी यात्रा समाप्त करने के लिए नहीं मिला है; एक त्रुटि सूचना आपको ड्राइवर की अनुपलब्धता की चेतावनी दिखाती है, और आप स्क्रीन 3 पर बने रहते हैं। आप अभी भी स्क्रीन 2, स्क्रीन 1 और यहां तक कि पहली स्क्रीन पर वापस आ सकते हैं।
आप कैब आरक्षण प्रक्रिया के एक अलग चरण में हैं, और आप केवल अगले स्तर पर जा सकते हैं यदि वर्तमान चरण में एक निर्दिष्ट कार्रवाई सफल होती है। उदाहरण के लिए, यदि आप स्क्रीन 1 पर गलत स्थान इनपुट करते हैं, तो आप स्क्रीन 2 पर आगे नहीं बढ़ पाएंगे, और जब तक आप स्क्रीन 2 पर यात्रा विकल्प नहीं चुनते हैं, तब तक आप स्क्रीन 3 पर आगे नहीं बढ़ पाएंगे, लेकिन आप जब तक आपकी यात्रा पहले से बुक नहीं हो जाती है, तब तक हमेशा पिछले चरण में वापस आएं।
उपरोक्त उदाहरण में, हमने कैब बुकिंग प्रक्रिया को कई गतिविधियों में विभाजित किया है, जिनमें से प्रत्येक बुकिंग की स्थिति के आधार पर किसी अन्य गतिविधि को कॉल करने के लिए अधिकृत हो भी सकती है और नहीं भी। इसे मॉडल करने के लिए एक स्टेट मशीन का उपयोग किया जाता है। सिद्धांत रूप में, इन चरणों/राज्यों में से प्रत्येक को स्वायत्त होना चाहिए, जिसमें एक को वर्तमान के समाप्त होने के बाद ही, सफलतापूर्वक या अन्यथा, अगले को बुलाया जाना चाहिए।
अधिक तकनीकी शब्दों में, राज्य मशीन हमें एक बड़ी जटिल कार्रवाई को अलग-अलग छोटी गतिविधियों के उत्तराधिकार में विभाजित करने में सक्षम बनाती है, जैसे कि पूर्ववर्ती उदाहरण में कैब बुकिंग गतिविधि।
घटनाएँ छोटे कार्यों को जोड़ती हैं, और एक राज्य से दूसरे राज्य में स्थानांतरण को संक्रमण कहा जाता है। हम आम तौर पर एक राज्य से दूसरे राज्य में बदलने के बाद कुछ कार्रवाइयां करते हैं, जैसे बैक एंड में बुकिंग बनाना, चालान जारी करना, उपयोगकर्ता विश्लेषण डेटा सहेजना, डेटाबेस में बुकिंग डेटा कैप्चर करना, यात्रा समाप्त होने के बाद भुगतान ट्रिगर करना आदि। .
इसलिए, एक राज्य मशीन के लिए सामान्य सूत्र इस प्रकार दिया जा सकता है:
वर्तमान स्थिति + कुछ कार्य / घटना = एक और राज्य
आइए देखें कि एक साधारण वीडियो प्लेयर एप्लिकेशन के लिए डिज़ाइन की गई स्टेट मशीन कैसी दिखेगी:
और हम इसे निम्नानुसार ट्रांज़िशन का उपयोग करके कोड में लागू कर सकते हैं:
from transitions import Machine class Video: # Define the states PLAYING = 'playing' PAUSED = 'paused' STOPPED = 'stopped' def __init__(self, source): self.source = source # Define the transitions transitions = [ # 1. A video can only be played when it is paused or stopped. {'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING}, # 2. A video can only be paused when it is playing. {'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED}, # 3. A video can only be stopped when it is playing or paused. {'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED}, ] # Create the state machine self.machine = Machine{ model = self, transitions = transitions, initial = self.STOPPED } def play(self): pass def pause(self): pass def stop(self): pass
अब, अगर हम एक और राज्य जोड़ना चाहते हैं, तो रिवाइंड कहें, हम इसे आसानी से निम्नानुसार कर सकते हैं:
from transitions import Machine class Video: # Define the states PLAYING = 'playing' PAUSED = 'paused' STOPPED = 'stopped' REWINDING = 'rewinding' # new def __init__(self, source): self.source = source # Define the transitions transitions = [ # 1. A video can only be played when it is paused or stopped. {'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.REWINDING, 'dest': self.PLAYING}, # new # 2. A video can only be paused when it is playing. {'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED}, {'trigger': 'pause', 'source': self.REWINDING, 'dest': self.PAUSED}, # new # 3. A video can only be stopped when it is playing or paused. {'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.REWINDING, 'dest': self.STOPPED}, # new # 4. A video can only be rewinded when it is playing or paused. {'trigger': 'rewind', 'source': self.PLAYING, 'dest': self.REWINDING}, #new {'trigger': 'rewind', 'source': self.PAUSED, 'dest': self.REWINDING}, # new ] # Create the state machine self.machine = Machine{ model = self, transitions = transitions, initial = self.STOPPED } def play(self): pass def pause(self): pass def stop(self): pass def rewind(self): pass
इस प्रकार, हम देख सकते हैं कि कैसे राज्य मशीनें एक जटिल कार्यान्वयन को सरल बना सकती हैं और हमें गलत कोड लिखने से बचा सकती हैं। राज्य मशीनों की क्षमताओं को जानने के बाद, अब यह समझना महत्वपूर्ण है कि राज्य मशीनों का उपयोग क्यों और कब करना है।
राज्य मशीनों का उपयोग उन अनुप्रयोगों में किया जा सकता है जिनमें अलग-अलग राज्य होते हैं। प्रत्येक चरण एक या अधिक बाद की अवस्थाओं को जन्म दे सकता है, साथ ही प्रक्रिया प्रवाह को समाप्त कर सकता है। एक स्टेट मशीन यूजर इनपुट या इन-स्टेट कंप्यूटेशंस को नियोजित करती है, यह चुनने के लिए कि किस राज्य में आगे प्रवेश करना है।
कई अनुप्रयोगों को एक "आरंभिक" चरण की आवश्यकता होती है, इसके बाद एक डिफ़ॉल्ट स्थिति होती है जो कई प्रकार की कार्रवाइयों की अनुमति देती है। पिछले और वर्तमान इनपुट, साथ ही राज्यों, सभी का निष्पादन की जाने वाली कार्रवाइयों पर प्रभाव पड़ सकता है। सिस्टम के "शट डाउन" होने पर सफाई के उपाय किए जा सकते हैं।
एक राज्य मशीन हमें उन इकाइयों को अधिक सारगर्भित रूप से अवधारणा और प्रबंधन में मदद कर सकती है यदि हम एक बेहद जटिल कार्य को छोटी, स्वतंत्र इकाइयों में तोड़ सकते हैं, जहां हमें बस यह वर्णन करने की आवश्यकता है कि एक राज्य दूसरे राज्य में कब संक्रमण कर सकता है और संक्रमण होने पर क्या होता है। हमें इस बात से चिंतित होने की आवश्यकता नहीं है कि सेटअप के बाद संक्रमण कैसे होता है। उसके बाद हमें केवल यह सोचने की जरूरत है कि कब और क्या, कैसे नहीं।
इसके अलावा, राज्य मशीनें हमें पूरी राज्य प्रक्रिया को बहुत ही अनुमानित तरीके से देखने देती हैं; एक बार ट्रांज़िशन सेट हो जाने के बाद, हमें कुप्रबंधन या गलत राज्य ट्रांज़िशन के बारे में चिंता करने की ज़रूरत नहीं है; अनुचित संक्रमण तभी हो सकता है जब राज्य मशीन ठीक से कॉन्फ़िगर की गई हो। हमारे पास एक राज्य मशीन में सभी राज्यों और संक्रमणों का एक व्यापक दृष्टिकोण है।
यदि हम एक राज्य मशीन का उपयोग नहीं करते हैं, तो हम या तो विभिन्न संभावित अवस्थाओं में अपने सिस्टम की कल्पना करने में असमर्थ हैं, या हम जाने-अनजाने अपने घटकों को एक साथ कसकर जोड़ रहे हैं, या हम राज्य संक्रमणों को अनुकरण करने के लिए कई और स्थितियाँ लिख रहे हैं, जो इकाई और एकीकरण परीक्षण को जटिल बनाता है क्योंकि हमें यह सुनिश्चित करना चाहिए कि सभी परीक्षण मामले सभी शर्तों और उपयोग की जाने वाली शाखाओं की संभावना को मान्य करने के लिए लिखे गए हैं।
राज्य मशीनें, निर्णय लेने वाले एल्गोरिदम विकसित करने की उनकी क्षमता के अलावा, अनुप्रयोग योजना के कार्यात्मक रूप हैं। जैसे-जैसे एप्लिकेशन अधिक जटिल होते जाते हैं, प्रभावी डिजाइन की आवश्यकता बढ़ती जाती है।
राज्य आरेख और फ़्लोचार्ट पूरे डिज़ाइन प्रक्रिया के दौरान उपयोगी और कभी-कभी आवश्यक होते हैं। स्टेट मशीनें न केवल एप्लिकेशन प्लानिंग के लिए महत्वपूर्ण हैं, बल्कि बनाने में भी आसान हैं।
आधुनिक समय की कंप्यूटिंग में राज्य मशीनों के कुछ प्रमुख लाभ निम्नलिखित हैं:
राज्य मशीनों के बारे में सब कुछ अच्छा नहीं है, वे कभी-कभी कमियां और चुनौतियां भी पैदा कर सकते हैं। यहाँ राज्य मशीनों के साथ कुछ सामान्य समस्याएं हैं:
स्टेट मशीन का उपयोग करते समय, आपके सिस्टम में आदर्श रूप से दो तार्किक घटक होने चाहिए:
राज्य मशीन को बुनियादी ढांचे के रूप में माना जा सकता है जो राज्य के संक्रमण को चलाता है; यह राज्य के संक्रमणों की पुष्टि करता है और संक्रमण के पहले, दौरान और बाद में कॉन्फ़िगर की गई क्रियाओं को निष्पादित करता है; हालांकि, यह नहीं पता होना चाहिए कि उन कार्यों में व्यावसायिक तर्क क्या किया जाता है।
इसलिए, सामान्य तौर पर, सही एब्स्ट्रैक्शन का उपयोग करके राज्य मशीन को मुख्य व्यवसाय तर्क से अलग करना एक अच्छा विचार है; अन्यथा, कोड का प्रबंधन एक दुःस्वप्न होगा।
यहां कुछ अन्य वास्तविक जीवन परिदृश्य हैं जहां हमें सावधानी के साथ राज्य मशीन तर्क को नियोजित करने की आवश्यकता है:
हमारे दैनिक जीवन में राज्य मशीनों की अवधारणा से लाभान्वित होने वाले कुछ व्यावहारिक अनुप्रयोग निम्नलिखित हैं:
जब आप ऑनलाइन ई-कॉमर्स साइट से कुछ खरीदते हैं, उदाहरण के लिए, यह विभिन्न चरणों से गुजरता है, जैसे ऑर्डर किया गया, पैक किया गया, शिप किया गया, रद्द किया गया, डिलीवर किया गया, भुगतान किया गया, रिफंड किया गया, और इसी तरह। संक्रमण स्वचालित रूप से तब होता है जब चीजें एक गोदाम या रसद केंद्र से गुजरती हैं और विभिन्न चरणों में स्कैन की जाती हैं, जैसे कि जब कोई उपयोगकर्ता रद्द करता है या धनवापसी चाहता है।
प्रोग्रामिंग में राज्य मशीनों की धारणा अत्यंत उपयोगी है। यह न केवल अधिक जटिल उपयोग केस ऐप्स विकसित करने की प्रक्रिया को सुव्यवस्थित करता है बल्कि आवश्यक विकास कार्य को भी कम करता है। यह आधुनिक-दिन की घटनाओं की अधिक सरल और सुरुचिपूर्ण समझ प्रदान करता है और जब सही ढंग से लागू किया जाता है, तो चमत्कार हो सकता है।