Memento备忘录模式、序列化与反序列化-设计模式-行为型

目录

1、场景直入与定义

2、代码示例

3、序列化与反序列化


 

1、场景直入与定义

我们都遇到过交换两个变量的值的场景:

int a=1234;
int b=3215;

如果要交换两个变量的值,需要有一个临时变量c当做过度:

int c=a;
a=b;
b=c;

临时变量c做了一个a值的保存,备忘录模式与这个思想差不多。你可以单独新建一个对象,用于保存另外一个对象的状态,然后可以用于备份与恢复。类似于“游戏存档存盘”、“word编辑回退”。当然保存的对象多了可以放到List或者栈里,进一步也可以序列化保存到磁盘上。

 

2、代码示例

 

假设,我在写一篇博客Article,写的过程中要保存或回退到上一个版本。版本保存用ArticleMemento,版本多了,统一放到栈里进行管理。

package behavioral.memento;

public class Article {

    private String title;
    private String content;
    private String imgs;

    public Article(String title, String content, String imgs) {
        this.title = title;
        this.content = content;
        this.imgs = imgs;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getImgs() {
        return imgs;
    }

    public void setImgs(String imgs) {
        this.imgs = imgs;
    }

    public ArticleMemento saveToMemento() {
        ArticleMemento articleMemento = new ArticleMemento(this.title,this.content,this.imgs);
        return articleMemento;
    }

    public void undoFromMemento(ArticleMemento articleMemento) {

        this.title = articleMemento.getTitle();
        this.content = articleMemento.getContent();
        this.imgs = articleMemento.getImgs();
    }

    @Override
    public String toString() {
        return "Article{" +
                "title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", imgs='" + imgs + '\'' +
                '}';
    }
}
package behavioral.memento;


public class ArticleMemento {
    private String title;
    private String content;
    private String imgs;

    public ArticleMemento(String title, String content, String imgs) {
        this.title = title;
        this.content = content;
        this.imgs = imgs;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    public String getImgs() {
        return imgs;
    }

    @Override
    public String toString() {
        return "ArticleMemento{" +
                "title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", imgs='" + imgs + '\'' +
                '}';
    }
}

 

package behavioral.memento;


public class Test {

    public static void main(String[] args) {
        ArticleMementoManager articleMementoManager = new ArticleMementoManager();

        Article article= new Article("设计模式A","博客内容A","博客图片A");

        ArticleMemento articleMemento = article.saveToMemento();

        articleMementoManager.addMemento(articleMemento);
        System.out.println("标题:"+article.getTitle()+" 内容:"+article.getContent()+" 图片:"+article.getImgs()+" 暂存成功");

        System.out.println("博客完整信息:"+article);


        System.out.println("修改博客start");

        article.setTitle("设计模式B");
        article.setContent("博客内容B");
        article.setImgs("博客图片B");

        System.out.println("修改博客end");

        System.out.println("博客完整信息:"+article);

        articleMemento = article.saveToMemento();
        articleMementoManager.addMemento(articleMemento);



        article.setTitle("设计模式C");
        article.setContent("博客内容C");
        article.setImgs("博客图片C");

        System.out.println("暂存回退start");

        System.out.println("回退出栈1次");
        articleMemento = articleMementoManager.getMemento();
        article.undoFromMemento(articleMemento);

        System.out.println("回退出栈2次");
        articleMemento = articleMementoManager.getMemento();
        article.undoFromMemento(articleMemento);



        System.out.println("暂存回退end");
        System.out.println("博客完整信息:"+article);

    }
}

https://github.com/phs999/DesignPatterns/tree/afefb7884290c88bb9d8da97c28b1abf7104013c/design_pattern/src/behavioral/memento

3、序列化与反序列化

有些场景,仅仅存放在内存中的另一个对象中并不能满足我们的需求,可能是对象过大过多,太占内存,可能我们需要永久的保存下来,就像游戏存档,这就需要把对象进行序列化然后保存到文件实现持久化保存。

比如坦克大战游戏中,需要保存整体所有对象的当前状态,需要将所有游戏对象序列化到本地文件。前提是需要序列化的类需要实现Serializable接口。

public void save() {
		File f=new File("d:/tank.data");
		ObjectOutputStream ooStream=null;
		try {
			ooStream=new ObjectOutputStream(new FileOutputStream(f));
			ooStream.writeObject(myTank);
			ooStream.writeObject(objects);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if (ooStream!=null) {
				try {
					ooStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	public void load() {
		File f=new File("d:/tank.data");
		ObjectInputStream oiStream=null;
		try {
			oiStream=new ObjectInputStream(new FileInputStream(f));
			myTank=(Tank) oiStream.readObject();
			objects=(List<GameObject>) oiStream.readObject();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			if (oiStream!=null) {
				try {
					oiStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

如果对象的某些属性不想被序列化,可以使用transient关键字屏蔽。

性能更好的序列化与反序列化考虑使用protobuf。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值