typescript: Memento Pattern
/**
* 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>
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号