1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| class Originator {
private state: string;
constructor(state: string) { this.state = state; console.log(`Originator: My initial state is: ${state}`); }
public doSomething(): void { console.log('Originator: I\'m doing something important.'); this.state = this.generateRandomString(30); console.log(`Originator: and my state has changed to: ${this.state}`); }
private generateRandomString(length: number = 10): string { const charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return Array .apply(null, { length }) .map(() => charSet.charAt(Math.floor(Math.random() * charSet.length))) .join(''); }
public save(): Memento { return new ConcreteMemento(this.state); }
public restore(memento: Memento): void { this.state = memento.getState(); console.log(`Originator: My state has changed to: ${this.state}`); } }
interface Memento { getState(): string;
getName(): string;
getDate(): string; }
class ConcreteMemento implements Memento { private state: string;
private date: string;
constructor(state: string) { this.state = state; this.date = new Date().toISOString().slice(0, 19).replace('T', ' '); }
public getState(): string { return this.state; }
public getName(): string { return `${this.date} / (${this.state.substr(0, 9)}...)`; }
public getDate(): string { return this.date; } }
class Caretaker { private mementos: Memento[] = [];
private originator: Originator;
constructor(originator: Originator) { this.originator = originator; }
public backup(): void { console.log('\nCaretaker: Saving Originator\'s state...'); this.mementos.push(this.originator.save()); }
public undo(): void { if (!this.mementos.length) { return; } const memento = this.mementos.pop();
console.log(`Caretaker: Restoring state to: ${memento.getName()}`); this.originator.restore(memento); }
public showHistory(): void { console.log('Caretaker: Here\'s the list of mementos:'); for (const memento of this.mementos) { console.log(memento.getName()); } } }
const originator = new Originator('Super-duper-super-puper-super.'); const caretaker = new Caretaker(originator);
caretaker.backup(); originator.doSomething();
caretaker.backup(); originator.doSomething();
caretaker.backup(); originator.doSomething();
console.log(''); caretaker.showHistory();
console.log('\nClient: Now, let\'s rollback!\n'); caretaker.undo();
console.log('\nClient: Once more!\n'); caretaker.undo();
|