Java 设计模式Java设计模式

Java设计模式 - 备忘录模式

2019-03-17  本文已影响0人  a57ecf3aaaf2

定义

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

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

实现

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

public class PathMemento {

    private HashMap<String, Object> backup;

    public PathMemento(HashMap<String, Object> backup) {
        this.backup = backup;
    }

    public void setBackup(HashMap<String, Object> backup) {
        this.backup = backup;
    }

    public HashMap<String, Object> getBackup() {
        return backup;
    }
}

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

public final class Beans {

    public static HashMap<String, Object> backupBean(Object bean) {
        HashMap<String, Object> 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<String, Object> 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<String, PathMemento> 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);
    }
}

本文由 Fynn_ 原创,未经许可,不得转载!

上一篇 下一篇

猜你喜欢

热点阅读