التعريف والبنية
يسمى وضع Memento أيضًا وضع الرمز المميز. يحدد GOF وضع المذكرة على النحو التالي: دون تدمير التغليف ، والتقاط الحالة الداخلية لكائن ما وحفظ هذه الحالة خارج الكائن. وبهذه الطريقة ، يمكن استعادة الكائن إلى حالته المحفوظة الأصلية لاحقًا.
عند الحديث عن وضع الأوامر ، ذكرنا ذات مرة أن استخدام دور الأمر المتوسط يمكن أن يدرك وظائف التراجع والإعادة. من التعريف ، يمكننا أن نرى أن وضع المذكرة يستخدم خصيصًا لتخزين الحالة التاريخية للكائن ، والتي هي ذات مساعدة كبيرة لتنفيذ وظائف التراجع وإعادة بشكل جيد. لذلك ، في وضع الأوامر ، يمكن تنفيذ وظائف التراجع والإعادة بالتراجع بالتزامن مع وضع المذكرة.
في الواقع ، لا يزال من السهل للغاية إدراك وظيفة حفظ حالة الكائن في لحظة معينة - ضع السمات المراد حفظها في الكائن في كائن متخصص في إدارة النسخ الاحتياطي ، واستدعاء الطريقة المتفق عليها لإعادة سمات النسخ الاحتياطي إلى الكائن الأصلي عند الحاجة. ولكن عليك إلقاء نظرة جيدة على السماح لكائن النسخ الاحتياطي الخاص بك بالوصول إلى الخصائص في الكائن الأصلي ، هل يعني ذلك أنه يتعين عليك الكشف عن جميع خصائص الخصائص الخاصة للكائن الأصلي للكائن في الحزمة؟ إذا كان نهجك قد كسر التغليف ، فعليك التفكير في إعادة إنشاء.
وضع المذكرة هو مجرد حل عام اقترحته GOF لقضية "استرداد الحالة الأصلية لكائن ما في وقت معين". لذلك ، من حيث كيفية الحفاظ على التغليف - بسبب عوامل مثل خصائص اللغة ، لا يتم وصف نمط المذكرة بالتفصيل ، ولكنه يفسر فقط الأفكار القائمة على C ++.
1) دور Memento: دور المذكرة يخزن الوضع الداخلي لـ "دور مبدأ المذكرة". يحدد "دور مبادئ المذكرة" الحالات الداخلية "دور البادئ المذكرة" المخزنة حسب الحاجة. لمنع كائنات أخرى بخلاف "دور البادئ المذكرة" من الوصول إلى المذكرات. المذكرات لديها بالفعل واجهتان. لا يمكن أن يرى "دور مدير المذكرات" الواجهة الضيقة التي توفرها المذكرة إلا ، فهي غير مرئية للسمات المخزنة في دور المذكرة. يمكن أن يرى "دور البادئ المذكرة" واجهة واسعة - يمكنك الحصول على السمات التي تضعها في دور المذكرة.
2) دور المذكرة (المنشئ) دور: "دور بدء المذكرة" ينشئ مذكرة لتسجيل حالتها الداخلية في اللحظة الحالية. استخدم المذكرات لاستعادة الحالة الداخلية عند الحاجة.
3) مدير مذكرة (القائم بأعمال القائمة) الدور: مسؤول عن توفير المذكرات. لا يمكن تشغيل محتوى المذكرة أو فحصه.
مخطط الفصل لوضع المذكرة بسيط حقًا:
تنفيذ الكود العام
Class Creparatator {private String State = "" ؛ السلسلة العامة getState () {Return State ؛ } public void setState (String State) {this.state = state ؛ } memento public createMemento () {return new memento (this.state) ؛ } public void restorememento (memento memento) {this.setState (memento.getState ()) ؛ }} class memento {private string state = "" ؛ MEMENTO العامة (String State) {this.state = state ؛ } السلسلة العامة getState () {return state ؛ } public void setState (String State) {this.state = state ؛ }} class caretaker {private memento memento ؛ memento getMemento () {return memento ؛ } public void setMemento (memento memento) {this.memento = memento ؛ }} client client client {public static void main (string [] args) {cempledator Cempling = new Censhatorator () ؛ Cemplor.SetState ("الحالة 1") ؛ system.out.println ("الحالة الأولية:"+censplatator.getState ()) ؛ القائم بأعمال القائم بالاتصال = New Caretaker () ؛ caretaker.setMemento (Censhatorator.Creatememento ()) ؛ censpl.setState ("status2") ؛ system.out.println ("الحالة بعد التغيير:"+censplatator.getState ()) ؛ cript.restorememento (caretaker.getMemento ()) ؛ system.out.println ("الحالة بعد الاسترداد:"+censplatator.getState ()) ؛ }}يوضح الرمز مثالًا للنسخ الاحتياطي الفردي للدولة. المنطق بسيط للغاية: يحتاج متغير الحالة في فئة المنشئ إلى النسخ الاحتياطي بحيث يمكن استعادته عند الحاجة ؛ في فئة Memento ، يوجد أيضًا متغير حالة يستخدم لتخزين الحالة المؤقتة لمتغير الحالة في فئة المنشئ ؛ ويتم استخدام فئة القائم بأعمال القائم بالإنشاء لإدارة فئة المذكرة ، والتي تُستخدم لكتابة الحالات أو استرداد الحالات في كائن المذكرة.
Multi State Multi-Backup Memo
في مثال عرض الكود العام ، تحتوي فئة المنشئ على متغير واحد فقط يحتاج إلى احتياطي ، في حين أن دور البادئ عادةً ما يكون جافابيا ، فهناك أكثر من متغيرات واحدة تحتاج إلى نسخ احتياطي في الكائن ، وأكثر من حالة واحدة تحتاج إلى نسخ احتياطي. هذه هي مذكرة متعددة الظهارات متعددة الظهور. هناك العديد من الطرق لتنفيذ المذكرات. هناك العديد من التشوهات وطرق المعالجة للمذكرات. لا يتم استخدام طرق مثل الكود العام بشكل عام. في معظم الحالات ، تكون المذكرات متعددة الحالات والنسخ الاحتياطية المتعددة. في الواقع ، من السهل جدًا تنفيذ الدول المتعددة والمتعددة. تتمثل الطريقة الأكثر استخدامًا في إضافة حاوية خريطة إلى Memento لتخزين جميع الحالات ، واستخدام حاوية MAP في فئة Caretaker لتخزين جميع النسخ الاحتياطية. أدناه نقدم مثالا على تعدد الولايات ومتعددة الخلايا:
Class Creparatator {private String State1 = "" ؛ سلسلة خاصة state2 = "" ؛ سلسلة خاصة 3 = "" ؛ السلسلة العامة getState1 () {return state1 ؛ } public void setState1 (String State1) {this.state1 = state1 ؛ } السلسلة العامة getState2 () {return State2 ؛ } public void setState2 (String State2) {this.state2 = state2 ؛ } السلسلة العامة getState3 () {return State3 ؛ } public void setState3 (String State3) {this.state3 = state3 ؛ } memento public createMemento () {return new memento (BeanUtils.backupprop (this)) ؛ } public void restorememento (memento memento) {beanUtils.RestoreProp (this ، mememento.getStateMap ()) ؛ } السلسلة العامة toString () {return "state1 ="+state1+"state2 ="+state2+"state3 ="+state3 ؛ }} class memento {private map <string ، Object> stateMap ؛ MEMENTO العامة (خريطة <string ، Object> map) {this.statemap = map ؛ } الخريطة العامة <string ، Object> getStateMap () {return StateMap ؛ } public void setStateMap (Map <String ، Object> StateMap) {this.stateMap = StateMap ؛ }} الفئة BeanUtils {خريطة ثابتة عامة <سلسلة ، كائن> backupprop (كائن بين) {map <string ، object> result = new hashmap <string ، object> () ؛ حاول {beaninfo beaninfo = interspector.getBeanInfo (bean.getClass ()) ؛ PropertyDescriptor [] واصفات = beaninfo.getPropertyDescriptors () ؛ لـ (propertyDescriptor des: descriptors) {String fieldName = des.getName () ؛ طريقة getter = des.getReadMethod () ؛ الكائن FieldValue = getter.invoke (Bean ، كائن جديد [] {}) ؛ if (! fieldname.equalsInsInoreCase ("class")) {result.put (fieldName ، fieldValue) ؛ }}}} catch (استثناء e) {E.PrintStackTrace () ؛ } نتيجة الإرجاع ؛ } restoreprop public static void (كائن فول ، خريطة <سلسلة ، كائن> propmap) {try {beaninfo beaninfo = interspector.getBeanInfo (bean.getclass ()) ؛ PropertyDescriptor [] واصفات = beaninfo.getPropertyDescriptors () ؛ لـ (propertyDescriptor des: descriptors) {String fieldName = des.getName () ؛ if (propmap.containskey (fieldName)) {method setter = des.getWriteMethod () ؛ setter.invoke (Bean ، Object [] {propmap.get (fieldName)}) ؛ }}} catch (استثناء e) {E.PrintStackTrace () ؛ }}} class caretaker {private map <string ، mememento> memmap = new hashmap <string ، mememento> () ؛ memento public getMemento (string index) {return memmap.get (index) ؛ } public void setMemento (فهرس السلسلة ، memento memento) {this.memmap.put (index ، memento) ؛ }} Class Client {public static void main (string [] args) {censplyator ori = new Criptator () ؛ القائم بأعمال القائم بالاتصال = New Caretaker () ؛ ori.setState1 ("الصين") ؛ ori.setState2 ("قوي") ؛ ori.setState3 ("الرخاء") ؛ system.out.println ("=== status action ===/n"+ori) ؛ caretaker.setmemento ("001" ، ori.creatememento ()) ؛ ori.setState1 ("software") ؛ ori.setState2 ("الهيكل") ؛ ori.setState3 ("ممتاز") ؛ system.out.println ("=== modified status ===/n"+ori) ؛ ori.restorememento (caretaker.getMemento ("001")) ؛ System.out.println ("=== Rested status ===/n"+ori) ؛ }} مزايا وعيوب وضع المذكرة ومزايا وضع المذكرة للسيناريوهات المعمول بها هي:
عندما تتغير الحالة في دور البادئ ، قد يكون تغيير خاطئ. يمكننا استعادة هذا التغيير الخاطئ باستخدام وضع المذكرة.
يتم حفظ حالة النسخ الاحتياطي خارج دور البادئ ، وبالتالي فإن دور البادئ لا يحتاج إلى إدارة حالة كل نسخة احتياطية.
عيوب وضع المذكرة:
في التطبيقات الفعلية ، يكون وضع المذكرة متعددة الدول ومتعددة الخلايا. يجب تخزين حالة دور البادئ في كائن المذكرة ، الذي يستهلك الموارد بشدة نسبيًا.
إذا كنت بحاجة إلى توفير عمليات التراجع ، فإن استخدام وضع المذكرة مناسب للغاية ، مثل عمليات معاملات JDBC ، CTRL+Z استرداد محرري النص ، إلخ.