मेरी राय में, UNDO / REDO को 2 तरीकों से मोटे तौर पर लागू किया जा सकता है। 1. कमांड लेवल (कमांड लेवल अनडू / रीडो कहा जाता है) 2. डॉक्यूमेंट लेवल (जिसे ग्लोबल अनडू / रीडो कहा जाता है)
कमांड स्तर: जैसा कि कई उत्तर बताते हैं, यह मेमेंटो पैटर्न का उपयोग करके कुशलता से प्राप्त किया गया है। यदि कमांड एक्शन को जर्नलिज्म करने में भी मदद करता है, तो एक रीडो आसानी से सपोर्ट करता है।
सीमा: एक बार कमांड के दायरे से बाहर होने के बाद, पूर्ववत करें / फिर से करना असंभव है, जो दस्तावेज़ स्तर (वैश्विक) पूर्ववत करें / फिर से ले जाता है
मुझे लगता है कि आपका मामला वैश्विक पूर्ववत / फिर से लागू होगा क्योंकि यह एक मॉडल के लिए उपयुक्त है जिसमें बहुत सारे मेमोरी स्पेस शामिल हैं। इसके अलावा, यह चुनिंदा पूर्ववत / फिर से करने के लिए भी उपयुक्त है। दो आदिम प्रकार हैं
- सभी मेमोरी पूर्ववत करें / फिर से करें
- ऑब्जेक्ट का स्तर पूर्ववत करें
"सभी मेमोरी पूर्ववत करें / फिर से करें" में, संपूर्ण मेमोरी को कनेक्टेड डेटा (जैसे कि एक पेड़, या एक सूची या एक ग्राफ) के रूप में माना जाता है और मेमोरी को ओएस के बजाय एप्लिकेशन द्वारा प्रबंधित किया जाता है। यदि C ++ में प्रभावी ढंग से संचालन को लागू करने के लिए अधिक विशिष्ट संरचनाएं सम्मिलित हैं तो नए और हटाए गए ऑपरेटर। यदि कोई नोड संशोधित किया गया है, तो बी। डेटा आदि को रखना और साफ़ करना, यह जिस तरह से कार्य करता है वह मूल रूप से संपूर्ण मेमोरी को कॉपी करना है (यह मानते हुए कि मेमोरी आवंटन पहले से ही अनुकूलित एल्गोरिदम का उपयोग करके आवेदन द्वारा अनुकूलित और प्रबंधित किया गया है) और इसे स्टैक में संग्रहीत करें। यदि स्मृति की प्रतिलिपि का अनुरोध किया जाता है, तो उथले या गहरी प्रतिलिपि की आवश्यकता के आधार पर पेड़ की संरचना की प्रतिलिपि बनाई जाती है। एक गहरी प्रतिलिपि केवल उस चर के लिए बनाई गई है जिसे संशोधित किया गया है। चूंकि प्रत्येक चर को कस्टम आवंटन का उपयोग करके आवंटित किया गया है, अगर जरूरत हो तो इसे हटाने के लिए एप्लिकेशन का अंतिम कहना है। चीजें बहुत दिलचस्प हो जाती हैं अगर हमें पूर्ववत / फिर से विभाजन करना पड़ता है जब ऐसा होता है कि हमें प्रोग्रामेटिक रूप से पूर्ववत करें / फिर से करें संचालन का एक सेट। इस मामले में, केवल उन नए चर, या हटाए गए चर या संशोधित चर को एक ध्वज दिया जाता है ताकि पूर्ववत करें / फिर से करें केवल उन स्मृतियों को पूर्ववत् / घटाता है यदि हम किसी वस्तु के अंदर आंशिक पूर्ववत / फिर से करना चाहते हैं तो चीजें और भी दिलचस्प हो जाती हैं। जब ऐसा होता है, तो "विज़िटर पैटर्न" के एक नए विचार का उपयोग किया जाता है। इसे "ऑब्जेक्ट स्तर पूर्ववत करें / फिर से करें" कहा जाता है या हटाए गए चर या संशोधित चर को एक ध्वज दिया जाता है ताकि पूर्ववत करें / फिर से करें केवल उन्ही मेमोरी को अनडू / रीडू करता है यदि हम किसी वस्तु के अंदर आंशिक पूर्ववत / फिर से करना चाहते हैं तो चीजें और भी दिलचस्प हो जाती हैं। जब ऐसा होता है, तो "विज़िटर पैटर्न" के एक नए विचार का उपयोग किया जाता है। इसे "ऑब्जेक्ट स्तर पूर्ववत करें / फिर से करें" कहा जाता है या हटाए गए चर या संशोधित चर को एक ध्वज दिया जाता है ताकि पूर्ववत करें / फिर से करें केवल उन्ही मेमोरी को अनडू / रीडू करता है यदि हम किसी वस्तु के अंदर आंशिक पूर्ववत / फिर से करना चाहते हैं तो चीजें और भी दिलचस्प हो जाती हैं। जब ऐसा होता है, तो "विज़िटर पैटर्न" के एक नए विचार का उपयोग किया जाता है। इसे "ऑब्जेक्ट स्तर पूर्ववत करें / फिर से करें" कहा जाता है
- ऑब्जेक्ट स्तर पूर्ववत करें / फिर से करें: जब पूर्ववत / फिर से करने की अधिसूचना को कहा जाता है, तो प्रत्येक वस्तु एक स्ट्रीमिंग ऑपरेशन को लागू करती है, जिसमें स्ट्रीमर ऑब्जेक्ट से पुराने डेटा / नए डेटा को प्राप्त करता है जिसे प्रोग्राम किया जाता है। जो डेटा डिस्टर्ब नहीं होता है, उसे छोड़ दिया जाता है। प्रत्येक ऑब्जेक्ट को तर्क के रूप में एक स्ट्रीमर मिलता है और UNDo / Redo कॉल के अंदर, यह ऑब्जेक्ट के डेटा को स्ट्रीम / अनस्ट्रीम करता है।
1 और 2 दोनों की विधियाँ हो सकती हैं जैसे 1. बिफोरंडो () 2. आफ्टरएंडो () 3. बिफोरडो () 4. आफ्टरएडो ()। इन तरीकों को मूल पूर्ववत / फिर से आदेश (संदर्भ आदेश नहीं) में प्रकाशित किया जाना है ताकि सभी ऑब्जेक्ट इन विधियों को भी लागू कर सकें ताकि विशिष्ट कार्रवाई हो सके।
एक अच्छी रणनीति 1 और 2. का संकर बनाना है। सुंदरता यह है कि ये विधियाँ (1 और 2) स्वयं कमांड पैटर्न का उपयोग करती हैं