备忘录模式(Memento Pattern)是一种行为型设计模式,它提供了一种在不破坏封装性的前提下,捕获一个对象的内部状态的方法。备忘录模式具有以下特点:
- 在不破坏封装性的前提下,捕获一个对象的内部状态。
- 可以在不破坏封装性的前提下,将对象的状态保存到外部存储中。
- 可以在不破坏封装性的前提下,将对象的状态恢复到之前保存的状态。
备忘录模式的主要角色有:
- 备忘录(Memento):定义了一个接口,用于封装对象的内部状态。
- 具体备忘录(Concrete Memento):实现备忘录接口,封装了对象的内部状态。
- 发起人(Originator):定义了一个接口,用于创建备忘录和恢复备忘录。
- 具体发起人(Concrete Originator):实现发起人接口,创建备忘录和恢复备忘录。
- 负责人(Caretaker):定义了一个接口,用于保存备忘录。
优点:
- 备忘录模式可以在不破坏封装性的前提下,捕获一个对象的内部状态,并将其保存到外部存储中。
- 备忘录模式可以在不破坏封装性的前提下,将对象的状态恢复到之前保存的状态。
- 备忘录模式可以实现对象状态的快照功能,方便用户在不同状态之间进行切换。
缺点:
- 备忘录模式可能会导致对象状态的冗余,因为每次保存备忘录都会创建一个新的对象状态。
- 备忘录模式可能会导致对象状态的不一致,因为在恢复备忘录时,对象状态可能已经发生了变化。
下面是一个使用 Java 实现的备忘录模式的例子:
// 备忘录接口
interface Memento {
}
// 具体备忘录
class ConcreteMemento implements Memento {
private String state;
public ConcreteMemento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起人接口
interface Originator {
Memento createMemento();
void restoreMemento(Memento memento);
}
// 具体发起人
class ConcreteOriginator implements Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
@Override
public Memento createMemento() {
return new ConcreteMemento(state);
}
@Override
public void restoreMemento(Memento memento) {
ConcreteMemento concreteMemento = (ConcreteMemento) memento;
state = concreteMemento.getState();
}
}
// 负责人接口
interface Caretaker {
void saveMemento(Memento memento);
Memento retrieveMemento();
}
// 具体负责人
class ConcreteCaretaker implements Caretaker {
private Memento memento;
@Override
public void saveMemento(Memento memento) {
this.memento = memento;
}
@Override
public Memento retrieveMemento() {
return memento;
}
}
// 客户端
public class Client {
public static void main(String[] args) {
ConcreteOriginator originator = new ConcreteOriginator();
originator.setState("State 1");
ConcreteCaretaker caretaker = new ConcreteCaretaker();
caretaker.saveMemento(originator.createMemento());
originator.setState("State 2");
originator.restoreMemento(caretaker.retrieveMemento());
System.out.println("Current state: " + originator.getState());
}
}
使用场景:
在浏览商品时保存购物车的状态,可以通过以下步骤实现:
-
用户在浏览商品时,购物车中的商品可能发生变化,例如添加新的商品、删除已有商品或修改商品数量。为了保存购物车的当前状态,可以在用户浏览商品之前调用购物车类(ShoppingCart)的
saveState()方法,创建一个备忘录对象(ShoppingCartMemento)。 -
将备忘录对象存储在购物车备忘录管理类(ShoppingCartCaretaker)中。这可以通过调用
setMemento()方法实现。 -
当用户完成商品浏览并准备结算时,可以通过调用购物车类的
restoreState()方法来恢复购物车的状态。在恢复状态之前,可以先检查购物车备忘录管理类中是否存在备忘录对象。如果存在,则调用getMemento()方法获取备忘录对象,并将其传递给restoreState()方法。
以下是一个简化的示例,说明如何在浏览商品时保存购物车的状态:
public class ECommerceSystem {
public static void main(String[] args) {
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.addItem(new Item("Item1", 100));
shoppingCart.addItem(new Item("Item2", 200));
// 保存购物车状态
ShoppingCartCaretaker caretaker = new ShoppingCartCaretaker();
caretaker.setMemento(shoppingCart.saveState());
// 用户浏览商品,购物车状态可能发生变化
shoppingCart.addItem(new Item("Item3", 300));
// 用户准备结算,恢复购物车状态
if (caretaker.getMemento() != null) {
shoppingCart.restoreState(caretaker.getMemento());
}
// 用户结算
// ...
}
}
在这个示例中,我们首先创建了一个购物车对象(shoppingCart),并添加了两个商品。然后,我们创建了一个购物车备忘录管理类对象(caretaker),并将购物车的当前状态保存到备忘录对象中。接下来,我们假设用户在浏览商品时添加了一个新的商品。最后,我们检查购物车备忘录管理类中是否存在备忘录对象,如果存在,则恢复购物车的状态。在实际应用中,可以根据需要在适当的时机调用saveState()和restoreState()方法。