设计模式21-备忘录模式

1.场景问题解决

1.1 场景描述

讨论一个游戏进度状态保存问题
游戏进度保存:对象状态,场景…,需要安全性,不能被非保存人读取到
如果在不使用数据库的情况下,怎么设计

1.2 OO设计

保存在数据库中

1.3 需求变动

1.4 带来问题

2.用设计模式改进

2.1 分析

[外链图片转存失败(img-4IaLCwOf-1568819792579)(https://raw.githubusercontent.com/bobshute/public/master/imgs/csdn/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/21%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F-1.png)]

2.2 重新设计

2.3 源码

  • MementoIF 接口
  • MementoCaretaker 管理者
public interface MementoIF {
}

public class MementoCaretaker {
	private HashMap<String, MementoIF> mementomap;

	public MementoCaretaker() {
		mementomap = new HashMap<String, MementoIF>();
	}

	//恢复备忘录
	public MementoIF retrieveMemento(String name) {
		return mementomap.get(name);
	}

	/**
	 * 备忘录赋值方法-保存备忘录
	 */
	public void saveMemento(String name, MementoIF memento) {
		this.mementomap.put(name, memento);
	}
}

  • Originator 发起者1,保存数据为HashMap
  • Originator2 发起者2,保存数据为ArrayList


public class Originator {
	private HashMap<String, String> state;

	public Originator() {
		state = new HashMap();
	}

	public MementoIF createMemento() {
		return new Memento(state);
	}

	public void restoreMemento(MementoIF memento) {
		state = ((Memento) memento).getState();
	}

	public void showState() {
		System.out.println("now state:" + state.toString());
	}

	public void testState1() {
		state.put("blood", "500");//游戏中自身血
		state.put("progress", "gate1 end");//游戏进度
		state.put("enemy", "5");//敌人数目

	}

	public void testState2() {
		state.put("blood", "450");//游戏中自身血
		state.put("progress", "gate3 start");//游戏进度
		state.put("enemy", "3");//敌人数目

	}

	private class Memento implements MementoIF {

		private HashMap<String, String> state;

		private Memento(HashMap state) {
			this.state = new HashMap(state);
		}
		private HashMap getState() {
			return state;
		}
		private void setState(HashMap state) {
			this.state = state;
		}
	}
}




public class Originator2 {
	private ArrayList<String> state;

	public Originator2() {
		state = new ArrayList<String>();
	}

	public MementoIF createMemento() {
		return new Memento(state);
	}

	public void restoreMemento(MementoIF memento) {
		state = ((Memento) memento).getState();
	}

	public void testState1() {
		state = new ArrayList<String>();
		state.add("blood:320");
		state.add("progress:gate2 mid");
		state.add("enemy:15");
	}

	public void testState2() {
		state = new ArrayList<String>();
		state.add("blood:230");
		state.add("progress:gate8 last");
		state.add("enemy:12");
	}

	public void showState() {
		System.out.println("now state:" + state.toString());
	}

	private class Memento implements MementoIF {

		private ArrayList<String> state;

		private Memento(ArrayList<String> state) {
			this.state = new ArrayList(state);
		}

		private ArrayList<String> getState() {
			return state;
		}

		private void setState(ArrayList<String> state) {
			this.state = state;
		}
	}

}
  • MementoTest 测试类

public class MementoTest {

	public static void main(String[] args) {
		MementoCaretaker mMementoCaretaker = new MementoCaretaker();
		Originator mOriginator = new Originator();
		Originator2 mOriginator2 = new Originator2();
		
		System.out.println("*****Originator*****");
		mOriginator.testState1();
		mMementoCaretaker
				.saveMemento("Originator", mOriginator.createMemento());
		mOriginator.showState();
		mOriginator.testState2();
		mOriginator.showState();
		mOriginator.restoreMemento(mMementoCaretaker
				.retrieveMemento("Originator"));
		mOriginator.showState();

		System.out.println("*****Originator 2*****");
		mOriginator2.testState1();
		mOriginator2.showState();
		mMementoCaretaker.saveMemento("Originator2",
				mOriginator2.createMemento());
		mOriginator2.testState2();
		mOriginator2.showState();
		mOriginator2.restoreMemento(mMementoCaretaker
				.retrieveMemento("Originator2"));
		mOriginator2.showState();

		//如果保存和恢复不一致则报错
		//System.out.println("*****Originator&&Originator 2*****");
	//	 mOriginator.restoreMemento(mMementoCaretaker
	//	 .retrieveMemento("Originator2"));
	//	 mOriginator.showState();

	}

}

3.设计模式总结

3.1 定义

备忘录模式:在不破坏封装的前提下,存储关键对象的重要状态,从而可以在将来把对象还原到存储的那个状态

3.2 分析思路

21备忘录模式-2

3.3 优缺点

  • 优点:
    状态存储在外面,不和关键对象混在一起,这可以帮助维护内聚
    提供了容易实现的恢复能力
    保持了关键对象的数据封装
  • 缺点:
    资源消耗上面备忘录对象会很昂贵
    存储和恢复状态的过程比较耗时

4. 设计模式使用场景及注意

4.1 使用场景

必须保存一个对象在某一个时刻的(整体或部分)状态,在对象以外的地方, 以后需要时恢复到先前的状态时

5.参考文章

内容总计于HeadFirst设计模式及相关视频

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章