definition: captures the internal state of an object without damaging the encapsulation, and saves the state outside the object. You can then restore the object to its previously saved state
Type: object behavior pattern
class Diagram:
When we are programming, we often need to save the middle state of the object, and we can revert to this state when we need it. 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 the deletion, and we can use Ctrl+z to return it. Then we can use the memo mode to implement.
structure of Memo mode Initiator: records the internal state of the current moment, responsible for defining what is the backup scope of the state, responsible for creating and recovering the memo data. Memo: responsible for storing the internal state of the initiator object , providing the internal state required by the initiator when needed. Management Role: manage memos, save and provide memos, and do not operate or check the contents of the memo.
Common Code Implementation
Initiator 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 ());
}//Memo class Memento {//is used to store the state variable private String state = "" in the originator class;
Public Memento (String state) {this.state = state;
Public String GetState () {return state;
public void SetState (String state) {this.state = state;
}//Manager is responsible for saving/providing memo class caretaker {private Memento Memento;
Public Memento Getmemento () {return Memento;
public void Setmemento (Memento Memento) {this.memento = Memento; } public class Simplemementoclient {public static void main (string[] args) {originator originator = new Origina
Tor ();
Originator.setstate ("State 1");
SYSTEM.OUT.PRINTLN ("Initial state:" + originator.getstate ()); Caretaker CARetaker = new Caretaker (); Caretaker.setmemento (Originator.creatememento ());
Save Memo Originator.setstate ("State 2");
SYSTEM.OUT.PRINTLN ("changed state:" + originator.getstate ()); Originator.restorememento (Caretaker.getmemento ());
Recovery status System.out.println ("post-restored state:" + originator.getstate ()); }
}
The code shows an example of a single State single backup, and the logic is simple: the state variable in the originator class needs to be backed up so that it can be recovered when needed, and in the Memento class, there is also a case, which stores the temporary status of the states variable in the originator class , and the caretaker class is used to manage the memo class, to write the status to the memo object or to retrieve the status.
Multi-state multiple backup memos
In the example of a generic code demo, the originator 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, and more than one status to back up, which is the multi-state multiple backup memo. There are many ways to implement a memo, Memo mode has a lot of deformation and processing methods, such as common code in a way generally will not be used, in most cases, the memo mode is a multiple-state multiple backup. In fact, multi-state multiple backup is also very simple, the most common method is that we add a map container in the memento to store all the states, in the caretaker class also use a map container to store all the backups. Here's an example of a multiple-state multiple backup:
Initiator 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 ());
Public String toString () {return "state1=" + state1 + "state2=" + state2 + "state3=" + state3;
}//Memo 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 {//Backup initiator All properties public static map<string, object> Backupprop (Object Bean) {Map<strin
G, object> result = 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);
A catch (Exception e) {e.printstacktrace ());
return result; }//Restore all properties of initiator public static void Restoreprop (Object bean, map<string, object> PropMap) {try {BeanInfo B
Eaninfo = 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)});
A catch (Exception e) {e.printstacktrace ());
}}//Admin role 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);
}//Client calls class Mementoclient {public static void main (string[] args) {originator Ori = new originator ();
Caretaker caretaker = new Caretaker ();
Ori.setstate1 ("China");
Ori.setstate2 ("powerful");
Ori.setstate3 ("prosperity");
System.out.println ("= = = Initialization state ===\n" + ori); Caretaker.setmemento ("001", Ori.creatememento ());
Backup Status ori.setstate1 ("Software");
Ori.setstate2 ("Architecture"); Ori.sEtState3 ("excellent");
System.out.println ("= = = Modified State ===\n" + ori); Ori.restorememento (Caretaker.getmemento ("001"));
Restore state System.out.println ("= = = after restored state ===\n" + ori); }
}
the pros and cons of Memo mode and the applicable scenario
The advantages of Memo mode are: When the status of the promoter role changes, it is possible that this is a wrong change, we use the memo mode can be changed to restore this 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.
The drawback of Memo mode: In practical Application, the memo mode is multiple state and multiple backup, the status of the promoter role needs to be stored in the memo object, the resource consumption is more serious.
If there is a need to provide a rollback operation, it is very appropriate to use the memo mode, such as JDBC transaction operations, text editor Ctrl+z recovery, and so on.