通俗易懂设计模式(备忘录模式)

69 阅读4分钟

备忘录模式(Memento Pattern)是一种行为型设计模式,它提供了一种在不破坏封装性的前提下,捕获一个对象的内部状态的方法。备忘录模式具有以下特点:

  1. 在不破坏封装性的前提下,捕获一个对象的内部状态。
  2. 可以在不破坏封装性的前提下,将对象的状态保存到外部存储中。
  3. 可以在不破坏封装性的前提下,将对象的状态恢复到之前保存的状态。

备忘录模式的主要角色有:

  1. 备忘录(Memento):定义了一个接口,用于封装对象的内部状态。
  2. 具体备忘录(Concrete Memento):实现备忘录接口,封装了对象的内部状态。
  3. 发起人(Originator):定义了一个接口,用于创建备忘录和恢复备忘录。
  4. 具体发起人(Concrete Originator):实现发起人接口,创建备忘录和恢复备忘录。
  5. 负责人(Caretaker):定义了一个接口,用于保存备忘录。

优点:

  1. 备忘录模式可以在不破坏封装性的前提下,捕获一个对象的内部状态,并将其保存到外部存储中。
  2. 备忘录模式可以在不破坏封装性的前提下,将对象的状态恢复到之前保存的状态。
  3. 备忘录模式可以实现对象状态的快照功能,方便用户在不同状态之间进行切换。

缺点:

  1. 备忘录模式可能会导致对象状态的冗余,因为每次保存备忘录都会创建一个新的对象状态。
  2. 备忘录模式可能会导致对象状态的不一致,因为在恢复备忘录时,对象状态可能已经发生了变化。

下面是一个使用 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());
    }
}

使用场景:

在浏览商品时保存购物车的状态,可以通过以下步骤实现:

  1. 用户在浏览商品时,购物车中的商品可能发生变化,例如添加新的商品、删除已有商品或修改商品数量。为了保存购物车的当前状态,可以在用户浏览商品之前调用购物车类(ShoppingCart)的saveState()方法,创建一个备忘录对象(ShoppingCartMemento)。

  2. 将备忘录对象存储在购物车备忘录管理类(ShoppingCartCaretaker)中。这可以通过调用setMemento()方法实现。

  3. 当用户完成商品浏览并准备结算时,可以通过调用购物车类的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()方法。