Java自学教程!浅谈Memento备忘录模式

public  void restoreMemento(Memento memento){

    this.menoy=memento.getMenoy();

    this.fruits=memento.getFruits();

}



public String toString(){

    return "Menoy:"+menoy+" ,Fruits:"+fruits;

}

}




Main类:



package zyr.dp.test;

import zyr.dp.memento.Gamer;

import zyr.dp.memento.Memento;

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.getMenoy());

        gamer.bet();

        if(gamer.getMenoy()<memento.getMenoy()/2){

            System.out.println("金钱过少,恢复到以前的状态:");

            gamer.restoreMemento(memento);

            System.out.println("此时状态为:"+gamer);

        }else if(gamer.getMenoy()>memento.getMenoy()){

            System.out.println("金钱增多,保存当前状态:");

            memento=gamer.createMemento();

            System.out.println("此时状态为:"+gamer);

        }

        try {

            Thread.sleep(500);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }



}

}




运行结果:



![1157683-20180701105620757-1245131485.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTE1NzY4My8yMDE4MDcvMTE1NzY4My0yMDE4MDcwMTEwNTYyMDc1Ny0xMjQ1MTMxNDg1LnBuZw?x-oss-process=image/format,png)



本程序的功能是根据循环次数随机的生成1~6这6个数字,如果数字是1,则金钱加一百,如果是二,则金钱减半,如果是6,则随机生成水果,水果分为好吃的和不好吃的,在保存的时候只保存好吃的水果,恢复的时候就只有好吃的水果了。当金钱少于当前备忘录中金钱的一半的时候就要恢复到备忘录的状态;当金钱大于备忘录的状态的时候就要备份当前的状态,备份的时候只备份好的水果以及当前金额,这就是游戏的功能,可以看到运行的结果的正确性。



  这里有几点要注意:、



1、窄接口和宽接口



   在代码中我已经标注出了窄接口和宽接口,如何定义这两种接口还要看这两种接口前面的修饰符,如果是默认的(只有本包的类可以使用),并且这些接口结合到一起可以完全的将本类的信息显示出来,那么就是宽接口;只能在本包之中使用,如果修饰符是public的接口,并且只能表示本类一部分信息,因为是public可以在其他包中使用的,就是窄接口,只能查看部分信息,因此是窄的。如下图所示,对于Main类所在的包,只能使用其他两个类中声明为public的字段和方法,因此在Main中只能使用窄接口来完成一定信息的读取getMenoy()。这只是一个概念,强调的是类、字段、方法的可见性。



2、可见性



   同时我们也知道,public修饰的字段和方法在任何包中都可以使用,private修饰的字段和方法只能在本类之中使用,protected修饰的方法可以在本包之中以及该类的子类(可以在其他包)中使用,默认的没有任何修饰的可以在本包之中使用。这就是四种修饰关键字的可见性。在编程的时候我们一定要考虑这些问题,不然就会导致我们不想看到的字段、方法、类被误用的结果。



3、将备份内容存盘并且读取



Memento类:



package zyr.dp.serializable;

import java.io.Serializable;

import java.util.ArrayList;

import java.util.List;

public class Memento implements Serializable {

private static final long serialVersionUID = 8497203738547925495L;



private int menoy;

private ArrayList fruits;



//窄接口,访问部分信息

public int getMenoy(){

    return menoy;

}



//宽接口,本包之内皆可访问

Memento(int menoy){

    this.menoy=menoy;

    fruits=new ArrayList();//每次调用的时候重新生成,很重要

}

//宽接口,本包之内皆可访问

List getFruits(){

    return (List) fruits.clone();

}

//宽接口,本包之内皆可访问

void  addFruits(String fruit){

    fruits.add(fruit);

}

}




Gamer类:



package zyr.dp.serializable;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.Random;

public class Gamer {

private static  String[] FruitsSame={"香蕉","苹果","橘子","柚子"};



private int menoy;

private List fruits=new ArrayList();

private  Random random=new Random();



public int getMenoy(){

    return menoy;

}



public Gamer(int menoy){

    this.menoy=menoy;

}



public void bet(){

    int next=random.nextInt(6)+1;

    if(next==1){

        menoy+=100;

        System.out.println("金钱增加了100,当前金钱为:"+menoy);

    }else if(next==2){

        menoy/=2;

        System.out.println("金钱减少了一半,当前金钱为:"+menoy);

    }else if(next==6){

        String f=getFruit();

        fruits.add(f);

        System.out.println("获得了水果:"+f+",当前金钱为:"+menoy);

    }else {

        System.out.println("金钱没有发生改变,当前金钱为:"+menoy);

    }

}



private String getFruit() {



    String prefix="";

    if(random.nextBoolean()){

        prefix="好吃的";

    }

    return prefix+FruitsSame[random.nextInt(FruitsSame.length)];

    

}



public Memento createMemento(){

    Memento m=new Memento(menoy);

    Iterator it=fruits.iterator();

    while(it.hasNext()){

        String fruit=(String)it.next();

        if(fruit.startsWith("好吃的")){

            m.addFruits(fruit);

        }

    }

    return m;

}



public  void restoreMemento(Memento memento){

    this.menoy=memento.getMenoy();

    this.fruits=memento.getFruits();

}



public String toString(){

    return "Menoy:"+menoy+" ,Fruits:"+fruits;

}

}




SerializableMain类:



package zyr.dp.test;

import java.io.*;

import zyr.dp.serializable.Gamer;

import zyr.dp.serializable.Memento;

public class SerializableMain {

private static String filename="game.dat";

public static void main(String[] args) {

    Gamer gamer=new Gamer(100);

    Memento memento=loadMemento();

    

    if(memento==null){

         memento=gamer.createMemento();

    }else{

        System.out.println("从上次保存处开始...");

        gamer.restoreMemento(memento);

    }

    

    for(int i=0;i<100;i++){

        System.out.println("当前状态:"+i);

        System.out.println("当前金额:"+gamer.getMenoy());

        gamer.bet();

        if(gamer.getMenoy()<memento.getMenoy()/2){

            System.out.println("金钱过少,恢复到以前的状态:");

            gamer.restoreMemento(memento);

            System.out.println("此时状态为:"+gamer);

        }else if(gamer.getMenoy()>memento.getMenoy()){

            System.out.println("金钱增多,保存当前状态:");

            memento=gamer.createMemento();

            saveMemento(memento);

            System.out.println("此时状态为:"+gamer);

        }

        try {

            Thread.sleep(500);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }



}

private static void saveMemento(Memento memento) {

    try {

        ObjectOutput o=new ObjectOutputStream(new FileOutputStream(filename));

        o.writeObject(memento);

        o.close();

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    }

}

private static Memento loadMemento() {

    Memento memento=null;

    ObjectInput in;

    try {

        in = new ObjectInputStream(new FileInputStream(filename));

        memento=(Memento)in.readObject();

        in.close();

    } catch (FileNotFoundException e) {

        System.out.println(e.toString());

    } catch (IOException e) {

        e.printStackTrace();

    } catch (ClassNotFoundException e) {

        e.printStackTrace();

    }

    return memento;

}

}




运行结果:



初次运行:



![1157683-20180701122807293-63729304.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTE1NzY4My8yMDE4MDcvMTE1NzY4My0yMDE4MDcwMTEyMjgwNzI5My02MzcyOTMwNC5wbmc?x-oss-process=image/format,png)



第二次运行:




## 总结

一般像这样的大企业都有好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。

这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。

最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!

提供【免费】的Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

**[Java全套进阶资料点这里免费领取](https://gitee.com/vip204888/java-p7)**

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。

这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。

最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!

提供【免费】的Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

**[Java全套进阶资料点这里免费领取](https://gitee.com/vip204888/java-p7)**

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/8ad636486a32704ceec03d3c98b5be2d.png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值