java 备忘录模式_Java设计模式,备忘录模式

定义

在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

备忘录模式的定义通俗易懂,下面会通过一个例子来解释备忘录模式的应用。

实现

定义一个具有记录绘图路径的备忘录类:

public class PathMemento {

private HashMap backup;

public PathMemento(HashMap backup) {

this.backup = backup;

}

public void setBackup(HashMap backup) {

this.backup = backup;

}

public HashMap getBackup() {

return backup;

}

}

声明一个工具类,处理对象的状态备份与恢复:

public final class Beans {

public static HashMap backupBean(Object bean) {

HashMap backup = new HashMap<>();

try {

BeanInfo info = Introspector.getBeanInfo(bean.getClass());

PropertyDescriptor[] desc = info.getPropertyDescriptors();

for (int i = 0; i < desc.length; i++) {

String name = desc[i].getName();

Method getter = desc[i].getReadMethod();

Object value = getter.invoke(bean, null);

if (!name.equals("class")) {

backup.put(name, value);

}

}

} catch (Exception e) {

e.printStackTrace();

}

return backup;

}

public static void restoreBean(Object bean, HashMap props) {

try {

BeanInfo info = Introspector.getBeanInfo(bean.getClass());

PropertyDescriptor[] desc = info.getPropertyDescriptors();

for (int i = 0; i < desc.length; i++) {

String name = desc[i].getName();

Method setter = desc[i].getWriteMethod();

if (props.containsKey(name)) {

setter.invoke(bean, props.get(name));

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

Path 类:

public class Path {

private int startX;

private int startY;

private int endX;

private int endY;

public PathMemento createMemento() {

return new PathMemento(Beans.backupBean(this));

}

public void restoreMemento(PathMemento memento) {

Beans.restoreBean(this, memento.getBackup());

}

@Override

public String toString() {

return "Path{" +

"startX=" + startX +

", startY=" + startY +

", endX=" + endX +

", endY=" + endY +

'}';

}

public int getStartX() {

return startX;

}

public void setStartX(int startX) {

this.startX = startX;

}

public int getStartY() {

return startY;

}

public void setStartY(int startY) {

this.startY = startY;

}

public int getEndX() {

return endX;

}

public void setEndX(int endX) {

this.endX = endX;

}

public int getEndY() {

return endY;

}

public void setEndY(int endY) {

this.endY = endY;

}

}

备忘录存储类,用于存储备忘录对象:

public class MementoBottle {

private HashMap mementos = new HashMap<>();

public void putMemento(String key, PathMemento memento) {

mementos.put(key, memento);

}

public PathMemento getMemento(String key) {

return mementos.get(key);

}

}

客户端示例:

public class Client {

public static void main(String[] args) {

Path p = new Path();

p.setStartX(0);

p.setStartY(0);

p.setEndX(16);

p.setEndY(22);

System.out.println(p);

MementoBottle bottle = new MementoBottle();

bottle.putMemento("m1", p.createMemento());

p.setStartX(3);

p.setStartY(2);

bottle.putMemento("m2", p.createMemento());

p.restoreMemento(bottle.getMemento("m1"));

System.out.println(p);

p.restoreMemento(bottle.getMemento("m2"));

System.out.println(p);

}

}

可以看出,当使用 Path 类进行路径绘制的时候,为了存储当前的路径信息,使用备忘录模式便可以达到目的。

备忘录模式相对来说比较简单,其主要实现的是对对象当前的信息进行备份,并在合适的时机恢复它。

总结

优点 实现了细节的封装,提供了“备份-恢复”模式,使得用户能够轻易地将需要备份和恢复的信息处理得得心应手。

缺点 如果需要备份的对象占用过多的内存,则每一次备份都会浪费系统资源,消耗更多内存。

Android 中的备忘录模式

public class Activity {

protected void onSaveInstanceState(Bundle outState) {

outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);

Parcelable p = mFragments.saveAllState();

if (p != null) {

outState.putParcelable(FRAGMENTS_TAG, p);

}

if (mAutoFillResetNeeded) {

outState.putBoolean(AUTOFILL_RESET_NEEDED, true);

getAutofillManager().onSaveInstanceState(outState);

}

getApplication().dispatchActivitySaveInstanceState(this, outState);

}

}

扩展

除了使用 Beans 工具类进行对象的备份,还可以使用以下两种方式处理: 属性直接赋值 这种方法适合对象中属性较少、内部实现简单的场景:

public class Order {

public int state;

public Memento createMemento() {

return new Memento(state);

}

public void restore(Memento memento) {

state = memento.getState();

}

}

实现 Cloneable 接口 通过实现该接口,并重写 Object 的 clone() 方法,完成对象的拷贝:

public class Order implements Cloneable {

public int state;

public Order createMemento() {

return clone();

}

public void restore(Order memento) {

state = memento.getState();

}

public int getState() {

return state;

}

public void setState(int state) {

this.state = state;

}

@Override

protected Order clone() {

try {

return (Order) super.clone();

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return null;

}

}

本文由知我者乎 原创,未经许可,不得转载!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值