【资料图】
备忘录模式(Memento Pattern)是一种结构型设计模式。这种模式就是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并放在外部存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。
备忘录模式的角色有三个:备忘录(Memento)角色、发起人(Originator)角色、负责人(Caretaker)角色
备忘录模式是由发起人(Originator)对象负责生成状态快照,其他对象不可修改状态。再将对象状态的副本存储在一个名为备忘录(Memento)的特殊对象中。除了创建备忘录的对象外,任何对象都不能访问备忘录的内容。其他对象必须使用指定接口与备忘录进行交互,它们可以获取快照的元数据(创建时间和操作名称等),但不能获取快照中原始对象的状态。
这种限制策略允许你将备忘录保存在通常被称为负责人(Caretakers)的对象历史中。由于负责人仅通过受限接口与备忘录互动,故其无法修改存储在备忘录内部的状态。同时,发起人拥有对备忘录所有成员的访问权限,从而能随时恢复其以前的某个状态。
// Memento.java 备忘录(Memento)角色,负责存储发起人传入的状态public class Memento { private String state; public Memento(String state) { System.out.println(this.getClass().getName() + "::Memento() [state = " + state + "]"); this.state = state; } public String getState() { return state; } public void setState(String state) { this.state = state; }}
// Originator.java 发起人(Originator)负责生成状态快照,即利用一个新备忘录对象将自己的内部状态存储起来public class Originator { private String state; // 每次创建一个新备忘录来保存状态 public Memento saveMemento() { System.out.println(this.getClass().getName() + "::saveMemento() [state = " + state + "]"); return new Memento(state); } // 从备忘录中恢复状态 public void restoreMemento(Memento memento) { this.state = memento.getState(); } public String getState() { return state; } public void setState(String state) { this.state = state; }}
// Caretaker.java 负责人(Caretaker)角色,只负责保存备忘录记录,不能修改备忘录对象的内容public class Caretaker { // 备忘录可以是一个记录,也可以就是一个对象,根据业务场景设置 private List mementoList = new ArrayList(); public void add(Memento memento) { System.out.println(this.getClass().getName() + "::add() [memento = " + memento.getClass().getName() + "]"); mementoList.add(memento); } public Memento get(int index) { return mementoList.get(index); } public List getMementoList() { return this.mementoList; }}
/* * 备忘录模式是在不暴露对象实现细节的情况下保存和恢复对象之前的状态。 * 先声明发起人Originator,再声明负责人Caretaker,发起人生成备忘录Memento * 通过负责人则保存备忘录历史记录,读取备忘录由负责人来完成。 */ Originator originator = new Originator(); Caretaker careTaker = new Caretaker(); // 发起人产生一个状态 originator.setState("state1"); // 覆盖了状态,那么前面的状态未保存 originator.setState("state2"); // 发起人生成备忘录,一般添加时直接保存即可 Memento memento = originator.saveMemento(); // 负责人保添加备忘录历史记录 careTaker.add(memento); // 直接生成备忘录并添加到负责人的备忘录列表 originator.setState("state3"); careTaker.add(originator.saveMemento()); originator.setState("state4"); careTaker.add(originator.saveMemento()); System.out.println("发起人当前的状态: " + originator.getState()); // 发起人通过负责人那里取出状态 originator.restoreMemento(careTaker.get(0)); System.out.println("第一个保存的状态: " + originator.getState()); originator.restoreMemento(careTaker.get(1)); System.out.println("第二个保存的状态: " + originator.getState()); // 遍历全部备忘录 for (int i = 0; i < careTaker.getMementoList().size(); i++) { // 外部一般不直接访问备忘录里面的状态,而是逐个恢复备忘录,再取出状态来 originator.restoreMemento(careTaker.get(i)); System.out.println("state: " + i + ")" + originator.getState()); }
// Memento.js 备忘录(Memento)角色,负责存储发起人传入的状态// 备忘录(Memento)角色,负责存储发起人传入的状态export class Memento { constructor(state) { console.log(this.constructor.name + "::Memento() [state = " + state + "]") this.state = state } getState() { return this.state } setState(state) { this.state = state }}
// Originator.js 发起人(Originator)负责生成状态快照,即利用一个新备忘录对象将自己的内部状态存储起来import { Memento } from "./Memento.js"export class Originator { constructor() { this.state = undefined } // 每次创建一个新备忘录来保存状态 saveMemento() { console.log( this.constructor.name + "::saveMemento() [state = " + this.state + "]" ) return new Memento(this.state) } // 从备忘录中恢复状态 restoreMemento(memento) { this.state = memento.getState() } getState() { return this.state } setState(state) { this.state = state }}
// Caretaker.js 负责人(Caretaker)角色,只负责保存备忘录记录,不能修改备忘录对象的内容export class Caretaker { constructor() { // 备忘录可以是一个记录,也可以就是一个对象,根据业务场景设置 this.mementoList = [] } add(memento) { console.log( this.constructor.name + "::add() [memento = " + memento.constructor.name + "]" ) this.mementoList.push(memento) } get(index) { return this.mementoList[index] } getMementoList() { return this.mementoList }}
import { Originator } from "../src/Originator.js"import { Caretaker } from "../src/Caretaker.js"export function test() { /* * 备忘录模式是在不暴露对象实现细节的情况下保存和恢复对象之前的状态。 * 先声明发起人Originator,再声明负责人Caretaker,发起人生成备忘录Memento * 通过负责人则保存备忘录历史记录,读取备忘录由负责人来完成。 */ const originator = new Originator() const careTaker = new Caretaker() // 发起人产生一个状态 originator.setState("state1") // 覆盖了状态,那么前面的状态未保存 originator.setState("state2") // 发起人生成备忘录,一般添加时直接保存即可 const memento = originator.saveMemento() // 负责人保添加备忘录历史记录 careTaker.add(memento) // 直接生成备忘录并添加到负责人的备忘录列表 originator.setState("state3") careTaker.add(originator.saveMemento()) originator.setState("state4") careTaker.add(originator.saveMemento()) console.log("发起人当前的状态: " + originator.getState()) // 发起人通过负责人那里取出状态 originator.restoreMemento(careTaker.get(0)) console.log("第一个保存的状态: " + originator.getState()) originator.restoreMemento(careTaker.get(1)) console.log("第二个保存的状态: " + originator.getState()) // 遍历全部备忘录 for (let i = 0; i < careTaker.getMementoList().length; i++) { // 外部一般不直接访问备忘录里面的状态,而是逐个恢复备忘录,再取出状态来 originator.restoreMemento(careTaker.get(i)) console.log("state: " + i + ")" + originator.getState()) }}// 执行测试;(function () { console.log("test start:") test()})()
不同语言实现设计模式:https://github.com/microwind/design-pattern
标签: