设计模式-Memento模式(备忘录模式)

什么是备忘录模式

类似玩游戏时,需要有保存游戏和加载游戏的功能,我们需要记录某个时刻某个对象的状态信息,在必要时进行回滚到那个时刻的状态。

备忘录模式就是为某个对象(目标对象)专门创建一个类,用来保存它的状态信息。注意Memento模式的状态类只保存了目标对象的部分信息,而Prototype模式中的原型对象则是完整克隆了对象的所有信息。

示例

示例程序类似一个大富翁游戏,涉及类比较少,有玩家Gamer、专门用于表示玩家状态的Memento、还有测试类Main

玩家Gamer,属性有金额money、水果袋子fruits、骰子random。主要的行为就是3个,createMemento表示创建一个状态对象保存当前的金额和水果,restoreMemento表示将当前对象回滚到传入的状态,bet就是掷骰子,改变目标对象的状态。


public class Gamer {

    private int money;
    private List fruits = new ArrayList();
    private Random random = new Random();
    private static String[] fruitsname = {
            "苹果", "葡萄", "香蕉", "橘子"
    };

    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 {
            System.out.println("什么都没有发生");
        }
    }

    public Memento createMemento() {
        Memento m = new Memento(money);
        Iterator it = fruits.iterator();
        while (it.hasNext()) {
            String f = (String) it.next();
            if (f.startsWith("好吃的")) {
                m.addFruit(f);
            }
        }
        return m;
    }

    public void restoreMemento(Memento memento) {
        this.money = memento.money;
        this.fruits = memento.getFruits();
    }

    public String toString() {
        return "[money = " + money + ", fruits = " + fruits + "]";
    }
    private String getFruit() {
        String prefix = "";
        if (random.nextBoolean()) {
            prefix = "好吃的";
        }
        return prefix + fruitsname[random.nextInt(fruitsname.length)];
    }
}

状态Memento,主要就是将目标对象的状态信息保存下来。


// 表示Gamer(主人公)状态的类
public class Memento {

    int money;
    ArrayList fruits;

    public Memento(int money) {
        this.money = money;
        this.fruits = new ArrayList();
    }

    public int getMoney() {
        return money;
    }

    void addFruit(String fruit) {
        fruits.add(fruit);
    }

    List getFruits() {
        return (List) fruits.clone();
    }
}

测试类,就是让玩家掷骰子,金额增加了就保存为最新的备份,如果钱少了就回滚上一个状态。

public class Main {
    public static void main(String[] args) {
        Gamer gamer = new Gamer(100);
        Memento memento = gamer.createMemento();
        for (int i = 0; i < 20; 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(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值