Definition und Struktur
Der Memento -Modus wird auch zum Token -Modus bezeichnet. GOF definiert den Memo -Modus als: Erfassen Sie ohne die Einkapselung den internen Zustand eines Objekts und speichern Sie diesen Zustand außerhalb des Objekts. Auf diese Weise kann das Objekt später in seinen ursprünglichen gespeicherten Zustand wiederhergestellt werden.
Wenn wir über den Befehlsmodus sprechen, haben wir einmal erwähnt, dass die Verwendung der Intermediate -Befehlsrolle die Funktionen von Rückgängigkeit und Wiederherstellung realisieren kann. Aus der Definition können wir feststellen, dass der Memo -Modus speziell verwendet wird, um den historischen Zustand des Objekts zu speichern. Daher können im Befehlsmodus und REO -Funktionen in Verbindung mit dem Memo -Modus implementiert werden.
Tatsächlich ist es immer noch sehr einfach, die Funktion des Speicherns des Status eines Objekts in einem bestimmten Zeitpunkt nur zu erkennen - die Attribute in das Objekt in ein Objekt zu speichern, das sich auf die Sicherungsverwaltung spezialisiert hat, und die vereinbarte Methode aufrufen, um die Sicherungsattribute bei Bedarf wieder in das ursprüngliche Objekt zu bringen. Aber Sie müssen einen guten Blick darauf werfen, damit Ihr Sicherungsobjekt auf die Eigenschaften des ursprünglichen Objekts zugreifen kann. Bedeutet dies, dass Sie alle Eigenschaften der ursprünglichen privaten Objekte im Paket offenlegen müssen? Wenn Ihr Ansatz die Einkapselung gebrochen hat, sollten Sie die Refactoring in Betracht ziehen.
Der Memorandum -Modus ist nur eine allgemeine Lösung, die von GOF für die Frage der "Wiederherstellung des ursprünglichen Zustands eines Objekts zu einem bestimmten Zeitpunkt" vorgeschlagen wurde. Daher wird das Memorandum -Muster in Bezug auf die Aufrechterhaltung der Kapselung aufgrund von Faktoren wie Sprachmerkmalen nicht ausführlich beschrieben, sondern nur die Ideen, die auf C ++ basieren.
1) Memento -Rolle: Die Memorandum -Rolle speichert den inneren Status der "Memorandum Initiator -Rolle". Die "Memorandum Initiator -Rolle" bestimmt, welche internen Zustände der "Memorandum Initiator -Rolle" bei Bedarf gespeichert werden. Um zu verhindern, dass andere Objekte als die "Memorandum -Initiatorrolle" auf Memos zugreifen. Memos haben tatsächlich zwei Schnittstellen. Die "Memo Manager -Rolle" kann nur die schmale Schnittstelle des Memos sehen - sie ist für die in der Memo -Rolle gespeicherten Attribute unsichtbar. Die "Memorandum Initiator -Rolle" kann eine breite Schnittstelle sehen - Sie können die Attribute, die Sie in die Memorandum -Rolle einfügen, einbringen.
2) Memo -Initiation (Urheber) Rolle: Die "Memo -Initiationsrolle" erstellt ein Memo, um ihren internen Zustand im aktuellen Moment aufzuzeichnen. Verwenden Sie Memos, um bei Bedarf den internen Zustand wiederherzustellen.
3) Memorandum Manager (Hausmeister) Rolle: Verantwortlich für das Speichern von Memos. Der Inhalt des Memos kann nicht betrieben oder überprüft werden.
Das Klassendiagramm des Memo -Modus ist wirklich einfach:
Allgemeine Code -Implementierung
Klasse Originator {private String state = ""; public String getState () {Return State; } public void setState (String Status) {this.state = STAAT; } 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 = STAAT; } public String getState () {Return State; } public void setState (String Status) {this.state = STAAT; }} Klasse für Hausmeister {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 ("Status 1"); System.out.println ("Anfangszustand:"+originator.getState ()); Hausmeister Hausmeister = neuer Hausmeister (); Caretaker.SetMemento (Originator.CreateMemento ()); Originator.SetState ("Status2"); System.out.println ("Status nach Änderung:"+originator.getState ()); Originator.Restorememento (Caretaker.getMemento ()); System.out.println ("Status nach Wiederherstellung:"+originator.getState ()); }}Der Code zeigt ein Beispiel für Einzelstaatenbackups. Die Logik ist sehr einfach: Die Statusvariable in der Urheberklasse muss gesichert werden, damit sie bei Bedarf wiederhergestellt werden kann. In der Memento -Klasse gibt es auch eine staatliche Variable, mit der der temporäre Zustand der Zustandsvariablen in der Urheberklasse gespeichert werden kann. und die Hausmeisterklasse wird verwendet, um die Memorandum -Klasse zu verwalten, mit der Zustände geschrieben oder Zustände in das Memorandum -Objekt abgerufen werden.
Multi-State-Multi-Backup-Memo
Im Beispiel der allgemeinen Codedemonstration hat die Urheberklasse nur eine staatliche Variable, die gesichert werden muss. In der Regel ist die Initiatorrolle in der Regel ein Javabäer. Dies ist ein Multi-Backup-Memo mit mehreren Staaten. Es gibt viele Möglichkeiten, Memos umzusetzen. Es gibt viele Verformungen und Verarbeitungsmethoden für Memos. Methoden wie allgemeiner Code werden im Allgemeinen nicht verwendet. In den meisten Fällen sind Memos mehrstaatlich und mehrere Backups. Tatsächlich ist es auch sehr einfach, mehrstaatlich und mehrfach zu implementieren. Die am häufigsten verwendete Methode ist das Hinzufügen eines Kartenbehälters zum Memento, um alle Zustände zu speichern, und verwenden einen Kartenbehälter in der Kartierklasse, um alle Backups zu speichern. Im Folgenden geben wir ein Beispiel für Multi-State und Multi-Backup:
Klasse 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 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, Objekt> map) {this.statemap = map; } public map <String, Objekt> getStatemap () {return Statemap; } public void setStatemap (MAP <String, Object> Statemap) {this.statemap = Statemap; }} class Beanutils {public static map <String, Objekt> Backupprop (Objektbean) {map <String, Objekt> result = new HashMap <String, Object> (); try {BeanInfo beanInfo = introspector.getBeanInfo (bean.getClass ()); PropertyDescriptor [] Descriptors = beanInfo.getPropertyDescriptors (); für (PropertyDescriptor Des: Descriptors) {String fieldname = Des.getName (); Methode getter = Des.getReadMethod (); Object fieldValue = getter.invoke (Bean, neues Objekt [] {}); if (! fieldname.equalSignoreCase ("Klasse")) {result.put (fieldname, fieldValue); }}}} catch (Ausnahme e) {e.printstacktrace (); } Rückgabeergebnis; } public static void restoreProp (Objektbean, Map <String, Object> propMap) {try {beanInfo beanInfo = introspector.getBeanInfo (Bean.getClass ()); PropertyDescriptor [] Descriptors = beanInfo.getPropertyDescriptors (); für (PropertyDescriptor Des: Descriptors) {String fieldname = Des.getName (); if (propMap.containsKey (fieldName)) {method setter = des.getwritemethod (); setter.invoke (Bean, neues Objekt [] {propMap.get (fieldName)}); }}} catch (exception e) {e.printstacktrace (); }}} Klasse für Hausmeister {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 (); Hausmeister Hausmeister = neuer Hausmeister (); ori.setState1 ("China"); ori.setState2 ("stark"); ori.setState3 ("Wohlstand"); System.out.println ("=== Initialisierungsstatus ===/n"+ori); Caretaker.SetMemento ("001", Ori.CreateMemento ()); ori.setState1 ("Software"); ori.setState2 ("Struktur"); ori.setState3 ("ausgezeichnet"); System.out.println ("=== modifizierter Status ===/n"+ori); ori.restorememento (Caretaker.getMemento ("001")); System.out.println ("=== restaurierte Status ===/n"+ori); }} Die Vor- und Nachteile des Memorandum -Modus und die Vorteile des Memorandum -Modus für anwendbare Szenarien sind:
Wenn sich der Status in der Initiatorrolle ändert, kann dies eine falsche Änderung sein. Wir können diese falsche Änderung im Memo -Modus wiederherstellen.
Der Status der Sicherung wird außerhalb der Initiatorrolle gespeichert, sodass die Initiatorrolle nicht den Status jeder Sicherung verwalten muss.
Nachteile des Memo -Modus:
In den tatsächlichen Anwendungen ist der Memorandum-Modus Multi-State und Multi-Backup. Der Zustand der Initiatorrolle muss im Memorandum -Objekt gespeichert werden, das Ressourcen relativ stark verbraucht.
Wenn Sie Rollback -Operationen bereitstellen müssen, ist die Verwendung des Memo -Modus sehr geeignet, z. B. JDBC -Transaktionsvorgänge, Strg+Z -Wiederherstellung von Texteditoren usw.