备忘录模式是一种对象行为型模式,它可以在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。 ,,备忘录模式的优点有:提供了一种可以恢复状态的机制,实现了内部状态的封装,简化了发起人类。 ,,备忘录模式的主要缺点是:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
在软件开发过程中,我们经常会遇到这样的问题:当一个对象的状态发生改变时,需要通知其他依赖于这个状态的对象,这时,我们可以使用备忘录模式来解决这个问题,备忘录模式是一种行为设计模式,它允许我们在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,当我们需要恢复这个对象的内部状态时,就可以直接从备忘录中获取,而不需要重新计算。
备忘录模式的主要角色有以下几个:
1、主题(Subject):负责维护备忘录,以及在状态发生改变时通知其他对象。
2、备忘录(Memento):用于存储主题的状态,以便在需要时恢复。
3、监听者(Caretaker):负责创建和删除备忘录,以及在状态发生改变时通知其他对象。
4、具体对象(ConcreteSubject):实现了主题接口的具体类,包含了具体的业务逻辑。
5、具体备忘录(ConcreteMemento):实现了备忘录接口的具体类,包含了具体的存储逻辑。
6、具体监听者(ConcreteCaretaker):实现了监听者接口的具体类,包含了具体的管理逻辑。
下面我们通过一个简单的例子来说明备忘录模式的使用方法:
假设我们有一个在线购物系统,用户可以对商品进行添加到购物车、从购物车移除等操作,为了实现这些功能,我们需要记录每个用户的购物车状态,当用户对购物车进行操作时,我们希望能够快速地恢复到上一次的状态,以便用户可以继续操作,这时,我们可以使用备忘录模式来实现这个需求。
我们定义一个抽象的主题类ShoppingCart
,它包含了一个ArrayList<Memento>
类型的成员变量mementos
,用于存储备忘录,它还需要提供一个方法addItem()
来添加商品到购物车,以及一个方法removeItem()
来从购物车移除商品,我们还需要提供一个方法getState()
来获取当前的购物车状态。
public abstract class ShoppingCart implements Memento { private List<Memento> mementos = new ArrayList<>(); public void addItem(Product product) { // 添加商品到购物车的逻辑 } public void removeItem(Product product) { // 从购物车移除商品的逻辑 } public List<Product> getItems() { // 获取购物车中所有商品的逻辑 } public void saveState(Memento state) { mementos.add(state); } }
我们定义一个具体的主题类OnlineShoppingCart
,它继承自抽象主题类ShoppingCart
,在这个类中,我们实现了抽象主题类的所有方法,我们还需要提供一个方法getState()
来获取当前的购物车状态,在这个方法中,我们需要遍历mementos
,找到最近的一个备忘录,然后使用这个备忘录来恢复当前的购物车状态,具体代码如下:
public class OnlineShoppingCart extends ShoppingCart { @Override public void addItem(Product product) { // ...添加商品到购物车的逻辑... saveState(this); // 保存当前状态到备忘录中 } @Override public void removeItem(Product product) { // ...从购物车移除商品的逻辑... saveState(this); // 保存当前状态到备忘录中 } @Override public List<Product> getItems() { // ...获取购物车中所有商品的逻辑... } @Override public Product getState() throws IllegalStateException, NoSuchStateException { for (int i = mementos.size() - 1; i >= 0; i--) { Memento state = mementos.get(i); if (state instanceof OnlineShoppingCart) { // 如果找到了对应的具体购物车状态 return ((OnlineShoppingCart) state).getItems(); // 直接返回该状态的商品列表 } else if (state instanceof Product) { // 如果找到了对应的具体商品状态 throw new NoSuchStateException("找到了具体商品状态,无法恢复为购物车状态"); // 这里抛出异常,因为无法恢复为购物车状态 } else if (state instanceof List) { // 如果找到了对应的具体商品列表状态(可能包含多个商品) return new ArrayList<>(((List<Product>) state)); // 将该列表转换为新的商品列表并返回 } else if (state != null) { // 如果找到了其他类型的备忘录(这里暂时忽略) throw new IllegalStateException("找到了其他类型的备忘录,无法恢复为购物车状态"); // 这里抛出异常,因为无法恢复为购物车状态 } else { // 如果没有找到任何备忘录(这里暂时忽略) throw new IllegalStateException("没有找到任何备忘录"); // 这里抛出异常,因为无法恢复为购物车状态(但实际上应该已经走到了这里) } } throw new NoSuchStateException("没有找到任何有效的备忘录"); // 这里抛出异常,表示无法恢复为购物车状态(实际上应该已经走到了这里) } }