Memomode
definition: captures the internal state of an object without compromising encapsulation, and saves the state outside that object. This allows the object to be restored to its previously saved state
Type: behavior class
Class Diagram:
When we are programming, we often need to save the middle state of the object, and when necessary, we can revert to this state. For example, when we are programming with Eclipse , if we write a mistake (such as accidentally accidentally deleting a few lines of code), we want to return to the state before deletion, we can use Ctrl + Z to return. At this point we can use the memo mode to achieve.
Structure of the memo pattern
Initiator: records the internal state of the current moment and is responsible for defining which state is part of the backup scope and responsible for creating and recovering Memo data.
Memo: responsible for storing the internal state of the initiator object, providing the internal state required by the initiator when needed.
Administrative roles: manage memos, save and provide memos.
Common Code implementations
Class Originator { private String state = ""; Public String getState () { return state; } public void SetState (String state) { this.state = state; } Public Memento Creatememento () { return new Memento (this.state); } public void Restorememento (Memento Memento) { this.setstate (memento.getstate ());} }
Class Memento { private String state = ""; Public Memento (String state) { this.state = state; } Public String getState () { return state; } public void SetState (String state) { this.state = state; }}
Class Caretaker { private Memento Memento; Public Memento Getmemento () { return Memento; } public void Setmemento (Memento Memento) { this.memento = Memento; }}
public class Client {public static void Main (string[] args) { originator originator = new originator (); Originator.setstate ("State 1"); SYSTEM.OUT.PRINTLN ("Initial state:" +originator.getstate ()); Caretaker caretaker = new Caretaker (); Caretaker.setmemento (Originator.creatememento ()); Originator.setstate ("State 2"); SYSTEM.OUT.PRINTLN ("changed state:" +originator.getstate ()); Originator.restorememento (Caretaker.getmemento ()); System.out.println ("Post-Restore Status:" +originator.getstate ());} }
The code shows an example of a single-state single-backup, which is very simple: theoriginator class has to be backed up in order to be restored when needed; in theMemento class, There is also a state variable used to store the temporary states of the originator class, whereas the caretaker class is used to manage the memo class. Used to write state to or retrieve status from a Memo object.
Multi-State multi-backup memo
In the example of a generic code demonstration, theoriginator class has only one state variable that needs to be backed up, and typically, the initiator role is usually a javaBean, with more than one variable in the object that needs to be backed up. There is more than one state that needs to be backed up, which is a multi-state multi-backup memo. There are many ways to implement a memo, the memo pattern has a lot of deformation and processing methods, such as general code in a way that is generally not used, in most cases, the memo mode is multi-state multi-backup. In fact, multi-state multi-backup is also very simple, the most common method is that we add a map container in the Memento to store all the state, in the caretaker class also use a map container to store all backups. Here we give an example of a multi-state multi-backup:
< Span style= "font-size:14px" >
class originator {private String state1 = ""; Private String State2 = ""; Private String State3 = ""; Public String getState1 () {return state1; } public void SetState1 (String state1) {this.state1 = state1; } public String GetState2 () {return state2; } public void SetState2 (String state2) {this.state2 = State2; } public String GetState3 () {return state3; } public void SetState3 (String state3) {this.state3 = State3; } public Memento Creatememento () {Return to New Memento (Beanutils.backupprop (this)); } public void Restorememento (Memento Memento) {Beanutils.restoreprop (this, Memento.getstatemap ()); The public String toString () {return "state1=" +state1+ "state2=" +state2+ "state3=" +STATE3; }}
class Memento {private map<string, object> Statemap; Public Memento (map<string, object> map) {this.statemap = map; } public map<string, Object> Getstatemap () {return statemap; } public void Setstatemap (map<string, object> statemap) {this.statemap = Statemap; }}
Class Beanutils {public static map<string, object> Backupprop (Object Bean) {map<string, object> res Ult = new hashmap<string, object> (); try{BeanInfo BeanInfo = Introspector.getbeaninfo (Bean.getclass ()); propertydescriptor[] descriptors = beaninfo.getpropertydescriptors (); for (PropertyDescriptor des:descriptors) {String fieldName = Des.getname (); Method getter = Des.getreadmethod (); Object fieldvalue = Getter.invoke (Bean, New object[]{}); if (!fieldname.equalsignorecase ("class")) {Result.put (fieldName, fieldvalue); }}}catch (Exception e) {e.printstacktrace (); } return result; } public static void Restoreprop (Object bean, map<string, object> PropMap) {try {BeanInfo BeanInfo = Introspector.getbeaninfo (Bean.getclass ()); Propertydescriptor[] descriptors = beaninfo.getpropertydescriptors (); for (PropertyDescriptor des:descriptors) {String fieldName = Des.getname (); if (Propmap.containskey (FieldName)) {Method setter = Des.getwritemethod (); Setter.invoke (Bean, New Object[]{propmap.get (FieldName)}); }}} catch (Exception e) {e.printstacktrace (); } }}
Class Caretaker { private map<string, memento> memmap = new hashmap<string, memento> (); Public Memento Getmemento (String index) { return Memmap.get (index); } public void Setmemento (String index, Memento Memento) { this.memMap.put (index, Memento);} }
Class Client {public static void Main (string[] args) { originator ori = new originator (); Caretaker caretaker = new Caretaker (); Ori.setstate1 ("China"); Ori.setstate2 ("Mighty"); Ori.setstate3 ("prosperity"); System.out.println ("= = = Initialize state ===\n" +ori); Caretaker.setmemento ("001", Ori.creatememento ()); Ori.setstate1 ("Software"); Ori.setstate2 ("architecture"); Ori.setstate3 ("excellent"); System.out.println ("= = = Modified state ===\n" +ori); Ori.restorememento (Caretaker.getmemento ("001")); System.out.println ("= = = Restore state ===\n" +ori);} }
The advantages and disadvantages of Memo mode and the applicable scenarios
The advantages of the memo pattern are:
When the status of the initiator role changes, it is possible that this is a wrong change, we can use the memo mode to restore the error.
The status of the backup is saved outside the initiator role, so that the initiator role does not need to manage the status of each backup.
Cons of Memo mode:
In practical applications, the memo mode is multi-state and multi-backup, the status of the initiator role needs to be stored in the memo object, the consumption of resources is more serious.
If there is a need to provide rollback operations, the use of Memo mode is ideal, such as JDBC transaction Operations, text editor Ctrl + Z recovery, and so on.
(18) Memo mode