你又是怎么理解「Memento Pattern」的呢

简介: 你又是怎么理解「Memento Pattern」的呢

备忘录模式

我们在使用文本编辑器编写文件时,如果不小心删除了某句话,可以通过撤销(undo )功能将文件恢复至之前的状态。有些文本编辑器甚至支持多次撤销,能够恢复至很久之前的版本。

使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息。然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态。

事例程序

  • 游戏是自动进行的
  • 游戏的主人公通过掷骰子来决定下一个状态
  • 当骰子点数为1的时候,主人公的金钱会增加
  • 当骰子点数为2的时候,主人公的金钱会减少
  • 当骰子点数为6的时候,主人公会得到水果
  • 主人公没有钱时游戏就会结束

在程序中,如果金钱增加,为了方便将来恢复状态,我们会生成Memento类的实例,将现在的状态保存起来。所保存的数据为当前持有的金钱和水果。如果不断掷出了会导致金钱减少的点数,为了防止金钱变为0而结束游戏,我们会使用Memento的实例将游戏恢复至之前的状态。

类的一览表

名字 说明
Memento game的状态类
Gamer 游戏的主人公
Main 测试

类图

image.png

代码

Memento

  • money表示主人公现在所持有的金钱数目,fruits表示现在为止所获得的水果。
public class Memento {
    int money;//所持金钱
    ArrayList<String> fruits;//所获得水果
    public int getMoney() {
        return money;
    }
    Memento(int money) {
        this.money = money;
        this.fruits = new ArrayList<>();
    }
//添加水果
    void addFruit(String fruit) {
        fruits.add(fruit);
    }
//获取所有水果
    List getFruit() {
        return (List) fruits.clone();
    }
}

Gamer

Gamer类是表示游戏主人公的类。它有3个子段,即所持金钱(money)获得的水果(fruits )以及一个随机数生成器(random)。而且还有一个名为fruitsname 的静态字段。

  • bet:,只要主人公没有破产,就会一直掷骰子,并根据骰子结果改变所持有的金钱数目和水果个数。
  • createMemento方法的作用是保存当前的状态(拍摄快照)。在createMemento方法中,会根据当前在时间点所持有的金钱和水果生成一个Memento类的实例,该实例代表了“当前Gamer的状态”,它会被返回给调用者。(只保存好吃的水果)
  • restoreMemento方法的功能与createMemento相反,它会根据接收到的Memento类的实例来将Gamer恢复为以前的状态
public class Gamer {
    private int money;
    private List<String> fruits = new ArrayList<>();
    private Random random = new Random();
    private static String[] fruitName = {"苹果", "葡萄", "香蕉", "橘子"};
    public Gamer(int money) {
        this.money = money;
    }
    public int getMoney() {
        return money;
    }
    public void bet() {
        //投骰子游戏
        int dice = random.nextInt(6) + 1;
        //加钱
        if (dice == 1) {
            money += 100;
            System.out.println("所持金钱增加了");
        } else if (dice == 2) {
            //减半
            money /= 2;
            System.out.println("所持金钱减半");
        } else if (dice == 6) {
            //获得水果
            String f = getFruit();
            System.out.println("获得水果" + f);
            fruits.add(f);
        } else {
            //3,4,5无事发生
            System.out.println("什么都没有发生");
        }
    }
  //拍摄快照
    public Memento createMemento() {
        Memento m = new Memento(money);
        Iterator<String> it = fruits.iterator();
        while (it.hasNext()) {
            String f = it.next();
            //保存好吃的水果
            if (f.startsWith("好吃的")) {
                m.addFruit(f);
            }
        }
        return m;
    }
  //撤销
    public void restoreMemento(Memento memento) {
        this.money = memento.money;
        this.fruits = memento.getFruit();
    }
    @Override
    public String toString() {
        return "money = " + money + " fruits = " + fruits;
    }
  //获得水果
    private String getFruit() {
        String prefix = "";
        if (random.nextBoolean()) {
            prefix = "好吃的";
        }
        return prefix + fruitName[random.nextInt(fruitName.length)];
    }
}

Main


public class Main {
    public static void main(String[] args) {
        Gamer gamer = new Gamer(100);
        Memento memento = gamer.createMemento();
        for (int i = 0; i < 100; i++) {
            System.out.println("===" + i);
            System.out.println("当前状态:" + gamer);
            gamer.bet();
            System.out.println("所持金钱:" + gamer.getMoney());
            if (gamer.getMoney() > memento.getMoney()) {
                System.out.println("保存状态");
                memento = gamer.createMemento();
            } else if (gamer.getMoney() < memento.getMoney() / 2) {
                System.out.println("金钱减少了很多,恢复");
                gamer.restoreMemento(memento);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

时序图

image.png



目录
相关文章
|
1月前
|
设计模式 C# C++
中介者模式(Mediator Pattern)
中介者模式是一种行为型设计模式,通过引入中介者对象来简化对象间的通信,减少多对象间的直接交互,降低系统耦合度。核心概念包括中介者、具体中介者和同事类。常见使用场景有聊天室、航空交通控制系统和GUI组件交互。优点是降低系统复杂度和提高灵活性,但中介者可能变得复杂,成为性能瓶颈。
34 3
|
1月前
|
存储 设计模式 C#
享元模式(Flyweight Pattern)
享元模式是一种结构型设计模式,通过共享对象来减少内存使用。它将对象分为共享和非共享部分,通过享元工厂管理和复用共享对象,适用于大量相似对象的场景,能显著节省内存并提高性能。典型应用包括文本编辑器中的字符样式和图形系统中的图形属性。
47 2
|
设计模式 Java uml
备忘录模式(Memento Pattern)
备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏对象封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将对象恢复到原先保存的状态。
115 3
|
存储 Java 程序员
行为型模式 - 备忘录模式(Memento Pattern)
行为型模式 - 备忘录模式(Memento Pattern)
|
设计模式 Java 数据库
Java设计模式-享元模式(Flyweight Pattern)
Java设计模式-享元模式(Flyweight Pattern)
|
设计模式 缓存 Java
java设计模式-原型模式(PrototypePattern)
java设计模式-原型模式(PrototypePattern)
|
设计模式 存储 Java
详解Java设计模式之原型模式(Prototype Pattern)
详解Java设计模式之原型模式(Prototype Pattern)
363 0
详解Java设计模式之原型模式(Prototype Pattern)
|
存储 缓存 Java
结构型模式 - 享元模式(Flyweight Pattern)
结构型模式 - 享元模式(Flyweight Pattern)
|
算法 Java 编译器
行为型模式 - 访问者模式(Visitor Pattern)
行为型模式 - 访问者模式(Visitor Pattern)