备忘录

定义:

       在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能够将该对象恢复到原先保存的状态。

适用场景:

       1、数据库事务回滚

       2、ctrl+z

       3、ie浏览器回退操作

优点:

       1、提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。

       2、实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息

       3、简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则

缺点:

       1、资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存空间。

组成元素:

       1、发起人(Originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,以及实现其他业务功能,它可以访问备忘录里的所有信息。

       2、备忘录(Memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

       3、管理者(CareTaker):对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问和修改。

类图如下:

抽象代码如下:

       1、定义备忘录Memento

public class Memento {

	private String state;
	
	public Memento(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
	
}

       2、定义管理者Caretaker

public class Caretaker {
	
	private Memento memento;

	public Memento getMemento() {
		return memento;
	}

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

       3、定义发起人Originator

public class Originator {

	private String state;
	
	public Memento createMemento() {
		return new Memento(state);
	}
	
	public void restoreMemento(Memento m) {
		this.setState(m.getState());
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
}

       4、定义客户类MementoPattern

public class MementoPattern {

	public static void main(String[] args) {
		Originator or = new Originator();
		Caretaker cr = new Caretaker();
		or.setState("S0");
		System.out.println("初始状态:"+or.getState());
		
		cr.setMemento(or.createMemento());
		or.setState("S1");
		System.out.println("新的状态:"+or.getState());
		or.restoreMemento(cr.getMemento());
		System.out.println("原始状态:"+or.getState());
	}
}

       5、输出结果如下:

示例代码如下: 

       由于于谦做了一件好事(扶老太太过马路),上帝决定给你奖励,上帝给了你四个箱子A、B、C、D,但是你只能选择一个,但是上帝是比较人性化的,它允许你反悔,即你先选择A,然后你反悔了选择B,这样也是可以的,我们用备忘录模式来实现一下这个例子。

       1、定义箱子备忘录BoxMemento

public class BoxMemento {

	private String boxName;
	
	public BoxMemento(String boxName) {
		this.boxName = boxName;
	}

	public String getBoxName() {
		return boxName;
	}

	public void setBoxName(String boxName) {
		this.boxName = boxName;
	}
}

       2、定义箱子管理者BoxCaretaker,只保存最新的4种回退状态:

public class BoxCaretaker {

	public List<BoxMemento>  boxMementoList = new ArrayList<>();

	private int top=0;

	public boolean push(BoxMemento b){
		if(top>=4){
			boxMementoList.add(b);
			boxMementoList.remove(0);
			top--;
			return true;
		}else{
			boxMementoList.add(b);
			top++;
			return true;
		}
	}
	public BoxMemento pop(){
		if(top<=0){
			return boxMementoList.get(0);
		}else {
			return boxMementoList.get(--top); 
		}
	}
}

       3、定义发起人于谦OriginatorYuQian

public class OriginatorYuQian {

	private String boxName;
	
	public BoxMemento createMemento() {
		return new BoxMemento(boxName);
	}
	
	public void restoreMemento(BoxMemento m) {
		this.setBoxName(m.getBoxName());
	}

	public String getBoxName() {
		return boxName;
	}

	public void setBoxName(String boxName) {
		this.boxName = boxName;
	}
}

       4、定义客户类MementoPattern

public class MementoPattern {

	public static void main(String[] args) {
		OriginatorYuQian or = new OriginatorYuQian();
		BoxCaretaker cr = new BoxCaretaker();
				
	
		or.setBoxName("箱子A");
		cr.push(or.createMemento());
		or.setBoxName("箱子B");
		cr.push(or.createMemento());
		or.setBoxName("箱子C");
		cr.push(or.createMemento());
		or.setBoxName("箱子D");
		cr.push(or.createMemento());
		/*因为咱们只保存4种回退状态,若set第5次,则第一次set的状态清除掉。*/
	//	or.setBoxName("箱子E");
	//	cr.push(or.createMemento());
		
		System.out.println("当前选择的箱子为:"+cr.boxMementoList.get(cr.boxMementoList.size()-1).getBoxName());
		System.out.println("回退第一次选择的箱子为:"+cr.pop().getBoxName());
		System.out.println("回退第二次选择的箱子为:"+cr.pop().getBoxName());
		System.out.println("回退第三次选择的箱子为:"+cr.pop().getBoxName());
		System.out.println("回退第四次选择的箱子为:"+cr.pop().getBoxName());
		System.out.println("回退第五次选择的箱子为:"+cr.pop().getBoxName());
	
	}
}

       5、输出结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值