A detailed explanation of the usage of the memo pattern of Java design pattern _java

Source: Internet
Author: User

Definition and structure

The memo (Memento) pattern is also called the tag (Token) pattern. GOF defines the memo mode as: capturing the internal state of an object without damaging the encapsulation, and saving the state outside the object. The object can then be restored to its previously saved state.

In the command mode, we mentioned that using the middle command role can achieve undo, redo function. From the definition you can see that the memo mode is specifically to store object history state, which is very good for the implementation of undo, redo function has a great help. So in the command mode, Undo, redo function can be implemented in conjunction with the memo mode.

In fact, it is very simple to implement the function of saving an object's state at a certain moment--putting the attributes to be saved in an object in an object that is specifically managed for backup, and when needed, calls the agreed-upon method to put the properties of the backup back in the original object. But you have to take a good look. Does it mean that you have to disclose all of the properties that are private to the object in order to allow your backup object to access the properties in the original object? If your approach has broken the package, consider refactoring it.

The memo mode is only a general solution to the problem of "restoring the original state of an object at some time" gof. Therefore, in how to maintain the encapsulation-due to the influence of language characteristics and other factors, Memo mode is not described in detail, just based on C + + elaborated the train of thought.


1 Memo (Memento) Role: The memo role stores the internal state of the memo initiation role. The memo initiation role determines which internal state of the memorandum role stores the memo initiation role, as needed. To prevent access to a memo for objects other than the memo initiation role. The memo actually has two interfaces, and the memo manager role can only see the narrow interface provided by the memo-it is not visible to the attributes stored in the memo role. The memo initiation role is able to see a wide interface--the ability to get the attributes that you put into the memo role.

2) The originator role: "Memo initiation role" Creates a memo that records its internal state at the current moment. Use memos to restore internal state when needed.

3 Memo Manager (caretaker) role: responsible for keeping good memos. The contents of the memo cannot be manipulated or checked.

The class diagram for Memo mode is really simple:

Common Code Implementation

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-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:

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; 
   
  } 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> 
    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); 
    }}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)}); 
    A 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 ("powerful"); 
    Ori.setstate3 ("prosperity"); SystEm.out.println ("= = = Initialization 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 ("= = = after restored state ===\n" +ori); 
 } 
}

The advantages and disadvantages of the

memo pattern and the applicable scenario
Memo mode are:
when the status of the initiator role changes, it is possible that this is a wrong change, and we can use the memo mode to restore this error change.
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. Disadvantages of the
Memo mode:
in practice, the memo mode is multiple states and multiple backups, the status of the initiator 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 appropriate to use the memo mode, such as JDBC transaction operations, text editor Ctrl+z recovery, and so on.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.