java备忘录模式

      备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

      备忘录模式很容易理解,实现起来也很简单。他相当于有一个第三方类,负责保存对象的状态,等待如果程序失败进行回滚。

       万万没想到很多人看过,里面王大锤的很多场景就是典型的备忘录模式:

       男人接口(尝试程序的接口):

/**
 * Men: 男人接口
 * 
 * @author xuejupo [email protected] create in 2015-12-30 上午10:16:51
 * 
 */
interface Men {

	/**
	 * pursue: 每个男人都有追女生方法
	 * 
	 * @param msg
	 *            追求的方法 void 返回类型
	 */
	void pursue(String msg);
}

 女人接口(保存对象状态的接口):

/**
 * Women:女人接口
 * 
 * @author xuejupo [email protected] create in 2015-12-30 上午10:19:07
 * 
 */
interface Women extends Cloneable {
	/**
	 * dealPursue: 每个女人都有对应的被追求的方法
	 * 
	 * @param msg
	 *            boolean 返回类型 表示同意否
	 */
	boolean dealPursue(Men m, String msg);

	// 获得妹子名字
	String getName();

	// 女人应该可以被保存状态
	public Women clone();
}

 王大锤(尝试程序):

/**
 * Wangdachui: 王大锤
 * 
 * @author xuejupo [email protected] create in 2015-12-30 上午10:28:15
 * 
 */
class Wangdachui implements Men {

	// 我的目标
	private Women target;

	/**
	 * setTarget: 设定追求目标
	 * 
	 * @param target
	 *            void 返回类型
	 */
	public void setTarget(Women target) {
		System.out.println("王大锤:哇,发现一个妹子:" + target.getName()
				+ ",好可爱,我要追她,让她崇拜我,爱上我,对我欲罢不能~~");
		this.target = target;
	}

	@Override
	public void pursue(String msg) {
		// TODO Auto-generated method stub
		if (this.target.dealPursue(this, msg)) {
			System.out
					.println("王大锤:哈哈," + this.target.getName() + "终于答应跟我在一起了");
		} else {
			System.out.println("王大锤:一定是我太英俊了," + this.target.getName()
					+ "自卑才不跟我在一起");
		}
	}
	/**
	* createMemento: 创建备份录
	* @return 
	* Memento  返回类型
	 */
	public Memento createMemento(){
		return new Memento(this.target);
	}
}

 阿美:(需要保存状态进行回滚的对象)

/**
 * Amei: 阿美女神
 * 
 * @author xuejupo [email protected] create in 2015-12-30 上午10:31:24
 * 
 */
class Amei implements Women, Cloneable {
	// 女神的黑名单
	private ArrayList<Men> blackList = new ArrayList<Men>();
	@Override
	public boolean dealPursue(Men m, String msg) {
		// TODO Auto-generated method stub
		// 如果在女神黑名单,直接拜拜
		if (this.blackList.contains(m)) {
			System.out.println("阿美:跟你说过不要找老娘了!");
			return false;
		}
		// 女神是很物质的
		if ("送钻戒".equals(msg) || "送别墅".equals(msg)) {
			System.out.println("阿美:看你这么有诚意,我就从了你把");
			return true;
		} else {
			System.out.println("阿美:这点东西就想打动老娘,真以为老娘没见过市面呀!");
			System.out.println("阿美:以后不要再来找老娘了!");
			// 把追求者加入黑名单
			this.blackList.add(m);
			return false;
		}
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "阿美";
	}

	/**
	 * clone: 重写的clone方法
	 * 
	 * @return
	 * @throws CloneNotSupportedException
	 *             Object 返回类型
	 */
	public Women clone() {
		// TODO Auto-generated method stub
		Amei amei = null;
		try {
			amei = (Amei) super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		amei.blackList = (ArrayList<Men>) this.blackList.clone();
		return amei;
	}
}

 备忘录

/**
 * Memento: 备忘录,用于保存妹子状态
 * 
 * @author xuejupo [email protected] create in 2015-12-30 上午10:54:40
 * 
 */
class Memento {
	// 保存状态,只保存一种状态
	public Women women;
	public Memento(Women women){
		this.women = women.clone();
	}
	public void setState(Women women) {
		this.women = women.clone();
	}

	public Women getState() {
		return this.women;
	}
}

 测试代码:

public class MementoTest {
	/**
	 * main:
	 * 
	 * @param args
	 *            void 返回类型
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		testMemento();
	}

	// 没有备忘录的测试程序
	private static void testNoMemento() {
		// 王大锤出场
		System.out.println("---------王大锤出场----------");
		Wangdachui wang = new Wangdachui();
		// 阿美出场
		System.out.println("---------阿美----------");
		Women amei = new Amei();
		// 王大锤看上阿美
		wang.setTarget(amei);
		// 王大锤给阿美送花
		System.out.println("---------王大锤给阿美送花----------");
		wang.pursue("送花");
		System.out.println("---------王大锤约阿美逛街----------");
		wang.pursue("逛街");
		System.out.println("---------王大锤给阿美送钻戒----------");
		wang.pursue("送钻戒");
	}

	/**
	 * testMemento: 测试备忘录 void 返回类型
	 */
	private static void testMemento() {
		// 王大锤出场
		System.out.println("---------王大锤出场----------");
		Wangdachui wang = new Wangdachui();
		// 阿美出场
		System.out.println("---------阿美----------");
		Women amei = new Amei();
		// 王大锤看上阿美
		wang.setTarget(amei);
		//追阿美之前先给阿美备份,万一追不到就回到起点:
		System.out.println("--------备份大法!---------");
		Memento memento = wang.createMemento();
		// 王大锤给阿美送花
		System.out.println("---------王大锤给阿美送花----------");
		wang.pursue("送花");
		System.out.println("---------王大锤约阿美逛街----------");
		wang.pursue("逛街");
		System.out.println("-------看来阿美不理我了,幸好我有备份大法------");
		wang.setTarget(memento.getState());
		System.out.println("---------王大锤给阿美送钻戒----------");
		wang.pursue("送钻戒");
	}
}

 结果:

---------王大锤出场----------
---------阿美----------
王大锤:哇,发现一个妹子:阿美,好可爱,我要追她,让她崇拜我,爱上我,对我欲罢不能~~
--------备份大法!---------
---------王大锤给阿美送花----------
阿美:这点东西就想打动老娘,真以为老娘没见过市面呀!
阿美:以后不要再来找老娘了!
王大锤:一定是我太英俊了,阿美自卑才不跟我在一起
---------王大锤约阿美逛街----------
阿美:跟你说过不要找老娘了!
王大锤:一定是我太英俊了,阿美自卑才不跟我在一起
-------看来阿美不理我了,幸好我有备份大法------
王大锤:哇,发现一个妹子:阿美,好可爱,我要追她,让她崇拜我,爱上我,对我欲罢不能~~
---------王大锤给阿美送钻戒----------
阿美:看你这么有诚意,我就从了你把
王大锤:哈哈,阿美终于答应跟我在一起了

       备忘录的适用场景不是很多,最近我在做项目的时候碰到一种:我们的项目用户修改用户信息需要修改好几个表。如果用户修改某一个表失败,应该将用户修改过的其他的表回滚回用户修改前的状态。这种情况很适合用备忘录模式。

猜你喜欢

转载自709002341.iteye.com/blog/2268543