你又是怎么理解「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



目录
相关文章
|
9月前
|
设计模式 Java uml
备忘录模式(Memento Pattern)
备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏对象封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将对象恢复到原先保存的状态。
77 3
|
6月前
|
设计模式
设计模式19 - 状态模式【State Pattern】
设计模式19 - 状态模式【State Pattern】
19 0
|
10月前
|
存储 设计模式 缓存
保留状态的秘密 - 深入了解Java备忘录模式(Memento Pattern)
保留状态的秘密 - 深入了解Java备忘录模式(Memento Pattern)
169 0
|
存储 Java 程序员
行为型模式 - 备忘录模式(Memento Pattern)
行为型模式 - 备忘录模式(Memento Pattern)
|
存储 算法 Java
行为型模式 - 模板模式(Template Pattern)
行为型模式 - 模板模式(Template Pattern)
|
设计模式 uml
设计模式实战-状态模式(State Pattern)(上)
设计模式实战-状态模式(State Pattern)(上)
129 0
|
设计模式
设计模式实战-状态模式(State Pattern)(下)
设计模式实战-状态模式(State Pattern)(下)
182 0
|
设计模式
设计模式实战-状态模式(State Pattern)(中)
设计模式实战-状态模式(State Pattern)(中)
113 0
设计模式实战-状态模式(State Pattern)(中)
|
C#
C#设计模式(19)——状态者模式(State Pattern)
原文:C#设计模式(19)——状态者模式(State Pattern) 一、引言   在上一篇文章介绍到可以使用状态者模式和观察者模式来解决中介者模式存在的问题,在本文中将首先通过一个银行账户的例子来解释状态者模式,通过这个例子使大家可以对状态者模式有一个清楚的认识,接着,再使用状态者模式来解决上一篇文章中提出的问题。
1058 0