The memo model has three roles.
1. Originator role: responsible for creating a memo to record the internal status of the current time, and can use the memo to restore the internal status. Implement other business functions.
2. Memo role: responsible for storing the internal status of the initiator.
3. Caretaker role: manage memos, provide the function of saving and obtaining memos, but it cannot access and modify the contents of memos.
/** * Initiator role * */ public class UnRedoOriginator { private String state; public UnRedoOriginator() { } public void setState(String state) { this.state = state; } public String getState() { return state; } public Memento createMemento() { return new Memento(state); } public void restoreMemento(Memento m) { if (m != null) { this.setState(m.getState()); } else { System.out.println("No state to recover"); } } }
/** * Memorandum * */ public class Memento { private String state; public Memento(String state) { this.state = state; } public void setState(String state) { this.state = state; } public String getState() { return state; } }
/** * Memo managers of undo and redo * */ public class UnRedoCaretaker { /* Memo list */ private List<Memento> mementoList; /* Memo list capacity, memo list capacity = maximum number of backward + 1 */ private int capacity = 3; /* Backward index */ private int undoIndex = -2; /* Forward index */ private int redoIndex = 0; public UnRedoCaretaker() { this.mementoList = new LinkedList<>(); } public UnRedoCaretaker(int capacity) { this(); this.capacity = capacity; } /** * Add memo * * @param memento */ public void addMemento(Memento memento) { // Before adding a note, remove the note after the current status for (int i = this.mementoList.size() - 1; i > this.undoIndex + 1; i--) { this.mementoList.remove(i); } if (this.mementoList.size() >= this.capacity) { this.mementoList.remove(0); } this.mementoList.add(memento); this.undoIndex = this.mementoList.size() - 2; this.redoIndex = this.mementoList.size(); } /** * Backward operation * * @return */ public Memento undo() { Memento result = null; if (this.undoIndex >= 0 && this.undoIndex < this.mementoList.size() - 1) { result = this.mementoList.get(this.undoIndex); this.undoIndex--; this.redoIndex--; } return result; } /** * Forward operation * * @return */ public Memento redo() { Memento result = null; if (this.redoIndex > 0 && this.redoIndex < this.mementoList.size()) { result = this.mementoList.get(this.redoIndex); this.redoIndex++; this.undoIndex++; } return result; } }
Aggregate the initiator role and memo manager role, and modify the initiator role class.
/** * Initiator role * */ public class UnRedoOriginator { private String state; private UnRedoCaretaker caretaker; public UnRedoOriginator() { this.caretaker = new UnRedoCaretaker(3); } private void setState(String state) { this.state = state; } public String getState() { return state; } private Memento createMemento() { return new Memento(state); } private void restoreMemento(Memento m) { if (m != null) { this.setState(m.getState()); } else { System.out.println("No state to recover"); } } public void setAndStoreState(String state) { this.setState(state); caretaker.addMemento(this.createMemento()); } public void undo() { this.restoreMemento(caretaker.undo()); } public void redo() { this.restoreMemento(caretaker.redo()); } }
Test.
/** * Test undo and redo * */ public class TestUnRedo { public static void main(String[] args) { UnRedoOriginator or = new UnRedoOriginator(); /* Status forward / backward not set */ or.undo(); or.redo(); /* Continuous add operation */ System.out.println(); int num = 1; operation(or, num++); operation(or, num++); operation(or, num++); operation(or, num++); /* The number of backward times exceeds the number of backward times */ back(or); back(or); back(or); /* Add a new action when backing up, and then back up */ System.out.println(); operation(or, num++); back(or); forward(or); forward(or);// Advance times more than can be advanced times /* Add a new action when backing up, and redo */ System.out.println(); back(or); operation(or, num++); forward(or); } private static void operation(UnRedoOriginator or, int name) { System.out.println("*******operation*******"); or.setAndStoreState("operation" + name); System.out.println("Current status:" + or.getState()); } private static void back(UnRedoOriginator or) { System.out.println("-------Back off-------"); or.undo(); System.out.println("Current status:" + or.getState()); } private static void forward(UnRedoOriginator or) { System.out.println("=======Forward======="); or.redo(); System.out.println("Current status:" + or.getState()); } }
The results are as follows.
No state to recover No state to recover *******Operation******* Current status: operation 1 *******Operation******* Current status: operation 2 *******Operation******* Current status: operation 3 *******Operation******* Current status: operation 4 -------Back up------- Current status: operation 3 -------Back up------- Current status: operation 2 -------Back up------- No state to recover Current status: operation 2 *******Operation******* Current status: operation 5 -------Back up------- Current status: operation 2 =======Forward======= Current status: operation 5 =======Forward======= No state to recover Current status: operation 5 -------Back up------- Current status: operation 2 *******Operation******* Current status: operation 6 =======Forward======= No state to recover Current status: operation 6