Mememento Patternwithout violating encapsulation,capture and externalize an object ' s internal state so, the object can be restore D to this state later. (without compromising encapsulation, capture the internal state of an object and save the state outside that object, so that the object can be restored to its original saved state.) )also known as Tonken mode
the words I don't know violating violation, blasphemy
Externalize give A. To form, make objective, make concrete
Internal The internal, inner , or inner body of a country;
1) Memo (Memento) Role: Memo role store internal state of "memo initiator role". The memo initiation role determines which internal states of the memos role store "Memo initiation role" as needed. To prevent the memo from being accessed by objects other than "Memo initiation role". Memos actually have two interfaces, and the memo manager role sees only the narrow interface provided by the memo-the attributes that are stored in the memo role are not visible. 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) Memo Initiation (originator) Role: "Memo initiates role" creates a memo to record its internal state at the current moment. Use memos to restore internal state when needed.
3) Memo Manager (caretaker) role: responsible for keeping memos. The contents of the memo cannot be manipulated or checked.
to look at a problem with a purpose is often clear.
public class Originator {private String state= ""; public void Changestate () { this.state= ' maybe not so good ';} public String getState () { return state;} public Voi D setState (String state) { this.state = state;} Public Memento Creatememote () { return new Memento (this.state);} public void Restoremomoto (Memento _memoto) { this.setstate (_memoto.getstate ());}}
public class Memento {private String state= ""; Public Memento (String _state) { this.state=_state;} public String getState () { return this.state;}}
public class Caretaker {private Memento Memoto; Public Memento Getmemoto () { return memoto;} public void Setmemoto (Memento memoto) { This.memoto=memoto;}}
public class Client {public static void Main (string[] args) { originator orihinator=new originator ();//Initiator Caretaker Caretaker=new caretaker (); Memo manager, cannot change content orihinator.setstate ("It s So Good");//Set Status Caretaker.setmemoto (Orihinator.creatememote () ); Create backup point orihinator.changestate (); Change state Orihinator.restoremomoto (Caretaker.getmemoto ()); Revert to Backup point}}/* * so the Memoto memo is a javabean that stores the data. * Why do we need caretaker? In order not to violate the Dimitri principle, only communicate with friends, backup class is not a friend, the system needs to just create a backup at some point * so the memo management class came out, it looked like a javabean, wrapped a layer on the memo, trouble, but this structure clear a lot of * Initiator does not need to communicate with backup class * * Example: Website-- browser--- cookies-- ... * The user sends a request to the server, the server creates a corresponding session object, sends the data to the browser and sets the cookie, for a period of time * The user can access the server, The server can determine which session object it is based on SessionID */
Multi-state backupIn the initiator member attribute multiple states, in the memo class is a hashmap, holds multiple states, through the Beanutils tool class injection parameters and return parameters.
public class Beanutils {//Put all attributes and values of the bean into HashMap public static hashmap<string,object> Backupprop (Object Bean) { hashmap<string,object> result = new hashmap<string,object> (); try {//Get bean description BeanInfo beaninfo= Introspector.getbeaninfo (Bean.getclass ());//Get Property Description propertydescriptor[] descriptors= Beaninfo.getpropertydescriptors ();//Traverse All properties for (PropertyDescriptor des:descriptors) {//property name String FieldName = Des.getname ();//Read properties by Method getter = Des.getreadmethod ();//Read property value Object Fieldvalue=getter.invoke (bean,new object[] {}), if (!fieldname.equalsignorecase ("class")) {Result.put (fieldName, Fieldvalue);}}} catch (Exception e) {//exception handling}return result;} Return the value of HashMap to the bean public static void Restoreprop (Object bean,hashmap<string,object> propmap) {try {// Get Bean description BeanInfo beanInfo = Introspector.getbeaninfo (Bean.getclass ());//Get Property Description propertydescriptor[] descriptors = Beaninfo.getpropertydescriptors ();//Traverse All properties for (PropertyDescriptor des:descriptors) {//property name String FieldName = Des.getname ();//IfThere is this property if (Propmap.containskey (fieldName)) {//write attribute Method setter = Des.getwritemethod (); Setter.invoke (Bean, new Object []{propmap.get (FieldName)});}} catch (Exception e) {//Exception handling System.out.println ("shit"); E.printstacktrace ();}}}
Multi-Backup Memocheckpoint, make a little change in the caretaker .
public class Caretaker {//the container that holds the memo private hashmap<string,memento> Memmap = new hashmap<string,memento> (); Public Memento Getmemento (String idx) {return memmap.get (idx);} public void Setmemento (String idx,memento Memento) {this.memMap.put (idx, Memento);}}
Permission DesignA private built-in class can only be accessed by the initiator, but the memo management needs to be correlated, and the empty interface can be used at this time, but the access properties can be reflected and modified by the data, which is a design method called "Dual interface Design", which puts the memento class inside Originator, this can only be accessed by originator.
< Span style= "line-height:1.71428571428571" > Dual interface design
Dual interface design, one of our classes can implement multiple interfaces, in the system design, if the object of security concerns, you can provide two interfaces, one is the normal interface of the business, to implement the necessary business logic, called the Wide Interface Another interface is an empty interface, and nothing is intended to provide access to modules outside the subsystem, such as container objects, which are called narrow interfaces, which are relatively safe because there is no way to manipulate the data in a narrow interface.
because one of the examples does seem simple, I modified it for about 40 minutes to combine the three functions, some of which are really bad, but at least understand the Tao.
public class Originator {private String state1= ""; State 1 private String state2= ""; State 2 private String state3= ""; State 3 public String getState1 () {return state1,} public void SetState1 (String state1) {this.state1 = state1;} publi C String GetState2 () {return state2;} public void SetState2 (String state2) {this.state2 = State2;} public String get State3 () {return state3;} public void SetState3 (String state3) {this.state3 = State3;}/** * Create a backup that reflects all the properties of the instance to ha The Shmap Collection * Then injects the startmap in the Memento by constructing the * @return * */Public Memento Creatememote () {return new Memento (Beanutils.backupp ROP (this)); }/** * Because of the permissions of the relationship, the external cannot pass in a Memento object, here will be used a hashmap set * through reflection, all the property values of the instance is replaced by the value in HashMap * @param map */public void R Estoremomoto (hashmap<string,object> map) {Beanutils.restoreprop (this, map);} /** * Built-in class, others cannot access * Implement an empty interface is for external association, in the actual development of a business interface, an empty interface for other sub-modules, through reflection can do whatever you like * @author Suibian */Private class Memento Implements imemento{private Hashmap<string,oBject> Startmap; Public Memento (hashmap<string,object> _startmap) {this.startmap=_startmap; } public hashmap<string, Object> Getstartmap () {return startmap; } public void Setstartmap (hashmap<string, object> startmap) {this.startmap = Startmap; }}/* Test using */@Override public String toString () {return "state1=" +state1+ "\ t state2=" +state2+ "\ t state3=" +state3;}
public class Caretaker { private hashmap<string,imemento> map=new hashmap<string,imemento> (); Public Imemento Getmemoto (String idx) { return map.get (IDX);}/** * Multiple Backups * @param idx time file * @param me Moto Backup Interface */public void Setmemoto (String idx,imemento memoto) { this.map.put (idx, Memoto);}}
public class Client {@SuppressWarnings ("unchecked") public static void main (string[] args) {Originator ori1 = new Origi Nator (); Caretaker caretaker = new Caretaker (); Ori1.setstate1 ("Backup 1 status 1"); Ori1.setstate2 ("Backup 1 Status 2"); Ori1.setstate3 ("Backup 1 Status 3"); Caretaker.setmemoto ("First", Ori1.creatememote ()); Originator Ori2 = new originator (); Ori2.setstate1 ("Backup 2 status 1"); Ori2.setstate2 ("Backup 2 status 2"); Ori2.setstate3 ("Backup 2 status 3"); Caretaker.setmemoto ("Second", Ori2.creatememote ()); System.out.println (Ori1.tostring ()); System.out.println (Ori2.tostring ()); SYSTEM.OUT.PRINTLN ("----------------------backup completed----------------------------"); Ori1.setstate1 ("Backup 1 status 1 Changed"); System.out.println ("changed:" +ori1.tostring ()); System.out.println ("-----------------------start Recovery-----------------------------"); Imemento memento = Caretaker.getmemoto ("First"); Get the backup instance from backup management//Get the Map object that is the attribute in the memento startmap and then convert it to a parameter hashmap<string,object> data= (hashmap<string, Object >) Beanutils.backupprop (Memento). Get ("Startmap"); For (entry<string, object> e:data.entryset ()) {System.out.println ("This is the backup data stored up:" +e.getkey () + "\ T" +e.getvalue () ); }//The data from the backup instance is injected into the ori1 by reflection to Ori1.restoremomoto. System.out.println ("------------------Data-------------------------after recovery"); System.out.println (Ori1.tostring ()); System.out.println (Ori2.tostring ()); }}/* Error Place * obtained by Beanutils.backupprop (Memento) is the object memento all property values of the class * and originator recovery requires a hashmap by reflection, a property name corresponding to a value, The HashMap obtained above is a property name, a HashMap object * Because the permission can only be recovered by originator, so the Restoremomoto () method is modified, not memento, and a HashMap object is passed.
I have to say, this is really troublesome.
I'm a rookie, I'm on my way.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Design Mode _ Memo Mode