Java设计模式——备忘录模式(Memento)

目录

一、简介

二、引入

三、掀开真面目


一、简介

Memento模式也叫备忘录模式,是行为模式的一种。用于记录对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

二、引入

备忘录模式中最经典的案例是闯关游戏,比如当我们进行到第20关的时候,设置一下备份。当我们在第30关死亡时,就不需要重新回到第一关开始,可以选择保存的第20关的备份,继续从第20关开始了。

其实,在生活中也有许多相似的案例。如,我们个人的学籍卡,当我们进入大学时,会保存你的信息(姓名、出生年月、性别、专业等),当专业发生变化时,需要更新你的个人信息,但此时由于操作员失误,将同名的另一个人信息修改了,此时就需要将信息还原到以前正确的状态。按照这个思路,我们写出自己的代码。如下:

学生个人信息类

package com.sht.memento;

/**
 * 学生个人信息
 * @author SHT
 *
 */
public class StudentInfo {
	/**
	 * 姓名
	 */
	private String name;
	/**
	 * 出生年月
	 */
	private String birthday;
	/**
	 * 性别
	 */
	private String sex;
	/**
	 * 专业
	 */
	private String profession;
	
	public StudentInfo() {
	}

	public StudentInfo(String name, String birthday, String sex, String profession) {
		this.name = name;
		this.birthday = birthday;
		this.sex = sex;
		this.profession = profession;
	}
	
	public void display() {
		System.out.println("学生信息[姓名:"+name+",出生年月:"+birthday+",性别:"+sex+",专业:"+profession);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getProfession() {
		return profession;
	}

	public void setProfession(String profession) {
		this.profession = profession;
	}
	
}

测试类

package com.sht.memento;
/**
 * 测试
 * @author SHT
 *
 */
public class TestDemo {
	public static void main(String[] args) {
		//入学时学生的个人信息
		StudentInfo start = new StudentInfo("小明", "1992-10-8", "男", "信息管理");
		System.out.println("------入学时信息---------");
		start.display();
		
		//备份学生的信息
		StudentInfo backup = new StudentInfo();
		backup.setName(start.getName());
		backup.setBirthday(start.getBirthday());
		backup.setSex(start.getSex());
		backup.setProfession(start.getProfession());
		
		//学生专业发生变化
		start.setProfession("IT");
		System.out.println("----中途改变专业后的信息----------");
		start.display();
		
		//发现改错了,需要还原
		start.setName(backup.getName());
		start.setBirthday(backup.getBirthday());
		start.setSex(backup.getSex());
		start.setProfession(backup.getProfession());
		System.out.println("-----最终学生的个人信息----------");
		start.display();
	}
}

测试结果

------入学时信息---------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
----中途改变专业后的信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:IT
-----最终学生的个人信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理

其实以上就是备忘录模式的思想。但在测试类(客户端)进行信息维护与还原,并不怎么专业,也没有充分发挥一个类只做一件事情的原则。所以,经过大神的重新设计,设计后的备忘录模式如下。

三、掀开真面目

1.Originor类

可以理解为上面的学生信息类,需要被保存信息内部对象状态的类。

2.Memento类

保存Originor对象信息状态的类,与Originor类具有相同的属性。

3.CareTaker

管理Memento对象的类

 

下面就让我们改写上面的代码

StudentInfo类

package com.sht.memento;

/**
 * 学生个人信息
 * @author SHT
 *
 */
public class StudentInfo {
	/**
	 * 姓名
	 */
	private String name;
	/**
	 * 出生年月
	 */
	private String birthday;
	/**
	 * 性别
	 */
	private String sex;
	/**
	 * 专业
	 */
	private String profession;
	
	public StudentInfo() {
	}

	public StudentInfo(String name, String birthday, String sex, String profession) {
		this.name = name;
		this.birthday = birthday;
		this.sex = sex;
		this.profession = profession;
	}
	
	public void display() {
		System.out.println("学生信息[姓名:"+name+",出生年月:"+birthday+",性别:"+sex+",专业:"+profession);
	}
	
	//这里增加两个方法
	//备份
	public Memento createMemento() {
		Memento m = new Memento(name,birthday,sex,profession);
		return m;
	}
	//还原
	public void setMemento(Memento m) {
		this.name = m.getName();
		this.birthday = m.getBirthday();
		this.sex = m.getSex();
		this.profession = m.getProfession();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getProfession() {
		return profession;
	}

	public void setProfession(String profession) {
		this.profession = profession;
	}
	
}

Memento类

package com.sht.memento;

public class Memento {
	/**
	 * 姓名
	 */
	private String name;
	/**
	 * 出生年月
	 */
	private String birthday;
	/**
	 * 性别
	 */
	private String sex;
	/**
	 * 专业
	 */
	private String profession;
	
	
	public Memento() {
	}
	
	public Memento(String name, String birthday, String sex, String profession) {
		this.name = name;
		this.birthday = birthday;
		this.sex = sex;
		this.profession = profession;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getProfession() {
		return profession;
	}
	public void setProfession(String profession) {
		this.profession = profession;
	}
	
	
}

CareTaker类

package com.sht.memento;

public class CareTaker {
	
	private Memento memento;

	public Memento getMemento() {
		return memento;
	}

	public void setMemento(Memento memento) {
		this.memento = memento;
	}
	
}

TestDemo类

package com.sht.memento;
/**
 * 测试
 * @author SHT
 *
 */
public class TestDemo {
	public static void main(String[] args) {
		//入学时学生的个人信息
		StudentInfo start = new StudentInfo("小明", "1992-10-8", "男", "信息管理");
		System.out.println("------入学时信息---------");
		start.display();
		
		//备份学生的信息
		CareTaker careTaker = new CareTaker();
		careTaker.setMemento(start.createMemento());
		
		//学生专业发生变化
		start.setProfession("IT");
		System.out.println("----中途改变专业后的信息----------");
		start.display();
		
		//发现改错了,需要还原
		start.setMemento(careTaker.getMemento());
		System.out.println("-----最终学生的个人信息----------");
		start.display();
	}
}

运行结果

------入学时信息---------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理
----中途改变专业后的信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:IT
-----最终学生的个人信息----------
学生信息[姓名:小明,出生年月:1992-10-8,性别:男,专业:信息管理

最后的结果是一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值