/** * Memento Pattern 备忘录是一种行为设计模式, 允许生成对象状态的快照并在以后将其还原。 * The Originator holds some important state that may change over time. It also * defines a method for saving the state inside a memento and another method for * restoring the state from it. */ class Originator { /** * For the sake of simplicity, the originator's state is stored inside a * single variable. */ private state: string; /** * * @param state */ constructor(state: string) { this.state = state; console.log(`Originator: My initial state is: ${state}`); } /** * The Originator's business logic may affect its internal state. Therefore, * the client should backup the state before launching methods of the * business logic via the save() method. */ 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}`); } /** * * @param length * @returns */ private generateRandomString(length: number = 10): string { const charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; return Array .apply(null, { length }) .map(() => charSet.charAt(Math.floor(Math.random() * charSet.length))) .join(''); } /** * Saves the current state inside a memento. */ public save(): Memento { return new ConcreteMemento(this.state); } /** * Restores the Originator's state from a memento object. */ public restore(memento: Memento): void { this.state = memento.getState(); console.log(`Originator: My state has changed to: ${this.state}`); } } /** * The Memento interface provides a way to retrieve the memento's metadata, such * as creation date or name. However, it doesn't expose the Originator's state. */ interface Memento { /** * * @returns */ getState(): string; /** * * @returns */ getName(): string; /** * * @returns */ getDate(): string; } /** * The Concrete Memento contains the infrastructure for storing the Originator's * state. */ class ConcreteMemento implements Memento { private state: string; private date: string; /** * * @param state */ constructor(state: string) { this.state = state; this.date = new Date().toISOString().slice(0, 19).replace('T', ' '); } /** * The Originator uses this method when restoring its state. * @returns */ public getState(): string { return this.state; } /** * The rest of the methods are used by the Caretaker to display metadata. * @returns */ public getName(): string { return `${this.date} / (${this.state.substr(0, 9)}...)`; } /** * * @returns */ public getDate(): string { return this.date; } } /** * The Caretaker doesn't depend on the Concrete Memento class. Therefore, it * doesn't have access to the originator's state, stored inside the memento. It * works with all mementos via the base Memento interface. */ class Caretaker { private mementos: Memento[] = []; private originator: Originator; /** * * @param originator */ constructor(originator: Originator) { this.originator = originator; } /** * */ public backup(): void { console.log('\nCaretaker: Saving Originator\'s state...'); this.mementos.push(this.originator.save()); } /** * * @returns */ 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); } /** * * @returns */ public showHistory(): string { //void let getstr=""; console.log('Caretaker: Here\'s the list of mementos:'); for (const memento of this.mementos) { console.log(memento.getName()); getstr=getstr+memento.getName()+","+memento.getState(); // return memento.getName(); } return getstr; } } let pubMemento1=""; let pubMemento2=""; let pubMemento3="Geovin Du"; let pubMemento4="geovindu"; /** * Client code. */ 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(''); pubMemento1=pubMemento1+caretaker.showHistory(); console.log('\nClient: Now, let\'s rollback!\n'); caretaker.undo(); console.log('\nClient: Once more!\n'); caretaker.undo(); let messageMemento: string = 'Hello World,This is a typescript!,涂聚文 Geovin Du.Web'; document.body.innerHTML = messageMemento+",<br/>one="+pubMemento1+",<br/>two="+pubMemento2+",<br/>three="+pubMemento3+",<br/>four="+pubMemento4+",<br/>TypeScript Memento Pattern 备忘录模式";
调用:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <head><title>TypeScript Hello Memento Pattern 备忘录</title> <meta name="Description" content="geovindu,涂聚文,Geovin Du"/> <meta name="Keywords" content="geovindu,涂聚文,Geovin Du"/> <meta name="author" content="geovindu,涂聚文,Geovin Du"/> </head> <body> <script src="dist/Mementots.js"> // //type="module" </script> </body> </html>
输出:
- typescript Memento Patterntypescript memento pattern memento pattern 19 memento pattern cpp typescript strategy pattern typescript iterator pattern typescript pattern state typescript template pattern method typescript mediator pattern responsibility typescript pattern chain typescript observer pattern