备忘录模式是一种对象行为模式,它在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。 该模式提供了一种可以恢复状态的机制,当用户需要时能够比较方便地将数据恢复到某个历史的状态。 ,,备忘录模式有三个角色:Originator(发起人)、Memento(备忘录)和Caretaker(管理员)。Originator负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据;Memento负责Originator当前状态的快照,之后需要时提供数据回滚;Caretaker管理Memento角色,将发起人对备忘录角色的使用权交给管理员。
在软件开发过程中,我们经常会遇到需要记录和追踪状态变化的情况,一个购物车应用可能需要记录用户的添加的商品、计算总价以及保存购物车状态等,这时,我们可以使用备忘录模式(Memento Pattern)来解决这个问题,备忘录模式是一种软件设计模式,它允许我们保存对象的内部状态,以便在后续操作中可以恢复到之前的状态。
备忘录模式的主要角色有三个:
1、发起人(Originator):负责创建备忘录对象,并提供添加、删除和查看历史记录的方法。
2、备忘录(Memento):负责存储发起人的历史记录,以便在需要时恢复到之前的状态。
3、监听者(Caretaker):负责管理备忘录对象,当备忘录对象不再需要时,将其保存到长期存储中。
下面我们通过一个简单的购物车示例来说明备忘录模式的用法。
我们定义一个购物车类(ShoppingCart),它包含一个商品列表(list)和一个当前状态(state),购物车类还包含一个方法,用于添加商品到商品列表中,并更新当前状态。
public class ShoppingCart { private List<String> items; private String state; public ShoppingCart() { items = new ArrayList<>(); } public void addItem(String item) { items.add(item); updateState(); } public void removeItem(String item) { items.remove(item); updateState(); } public String getState() { return state; } private void updateState() { StringBuilder sb = new StringBuilder(); sb.append("Current items: ["); for (String item : items) { sb.append(item).append(", "); } sb.delete(sb.length() - 2, sb.length()); sb.append("]"); state = sb.toString(); } }
我们定义一个备忘录类(Memento),它包含一个字符串变量(data),用于存储发起人的状态,备忘录类还包含一个构造函数,用于从发起人处获取状态数据,以及一个方法,用于将状态数据写入发起人。
public class Memento implements Serializable { private String data; public Memento(String data) { this.data = data; } public String getData() { return data; } }
我们定义一个负责人类(Originator),它包含一个购物车对象和一个备忘录对象,负责人类还包含一个构造函数,用于初始化购物车对象和备忘录对象,以及添加、删除和查看历史记录的方法,负责人类还包含一个方法,用于从最近的备忘录中恢复到之前的状态。
public class Originator implements Serializable { private ShoppingCart shoppingCart; private List<Memento> mementos; private int currentStateIndex; public Originator() { shoppingCart = new ShoppingCart(); mementos = new ArrayList<>(); currentStateIndex = -1; } public void add(String item) { shoppingCart.addItem(item); saveState(); // 将当前状态保存到备忘录中 } public void remove(String item) { shoppingCart.removeItem(item); saveState(); // 将当前状态保存到备忘录中 } public String getState() { return shoppingCart.getState(); // 从购物车对象中获取当前状态 } public Memento getMemento(int index) throws Exception { // 从指定索引处获取备忘录对象的副本(深拷贝) if (index >= mementos.size()) throw new Exception("Invalid index"); // 如果索引无效,抛出异常 return (Memento) mementos.get(index).clone(); // 否则返回备忘录对象的副本(深拷贝) } public void restore(int index) throws Exception // 从指定索引处恢复到之前的状态(深拷贝) { if (index >= mementos.size()) throw new Exception("Invalid index"); else shoppingCart.setState((String)((Memento)mementos.get(index)).getData()); currentStateIndex = index;} // 如果索引无效,抛出异常;否则恢复到之前的状态(深拷贝)