【问题和常用方法的弊端】


 

【解决思路】

代码分离,分为三个模块:“备忘录”(即备忘录实体)、“备忘发起者”(发起备忘录的修改和恢复)和“备忘录管理者”(保存备忘录,并对外提供备忘录实体)

 

【前期准备:定义三个模块】

1) 备忘录:“备忘录”存储“备忘发起者”的内部状态。“备忘发起者”根据需要决定“备忘录”存储“备忘发起者”的哪些内部状态。为了防止“备忘发起者”以外的其他对象访问“备忘录”。“备忘录”实际上有两个接口,“备忘录管理者”只能看到“备忘录”提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。

  2) 备忘发起者:创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用“备忘录”恢复内部状态。

  3) 备忘录管理者:负责保存好备忘录。不能对“备忘录”的内容进行操作或检查。

 

【模块职责】

1) 备忘发起者

(1)创建一个含有当前的内部状态的备忘录对象。

(2)使用备忘录对象存储其内部状态。

  2) 备忘录管理者

(1)负责保存备忘录对象。

(2)不检查备忘录对象的内容。

 

【具体实现】

将“备忘录”设成“备忘发起者”类的内部类,从而将“备忘录”对象封装在“备忘发起者”里面;在外部提供一个标识接口 “备忘录接口”给“备忘录管理者”以及其他对象。这样,“备忘发起者”类看到的是“备忘录”的所有接口,而“备忘录管理者”以及其他对象看到的仅仅是标识接口 “备忘录接口”所暴露出来的接口。

 

【代码】

1、备忘录接口

public interface MemotoI {

}

2、发起者

public class Originator {

    private string name;

    private string sex;

    private int age;

    Caretaker caretaker = new Caretaker();

    public Memento creatMementoObject() {
        return new Memento(name,sex,age) ;
    }

    /**
     * 将发起人恢复到备忘录对象所记载的状态
     */
    public void restoreMemento(MemotoI momI) {

        this.setName(((Memento) momI).getName());

        this.setSex(((Memento) momI).getSex());

        this.setAge(((Memento) momI).getAge());

        System.out.println("恢复备忘录 ,恢复至状态:name==" + ((Memento) momI).getName()+"—sex:"+((Memento) momI).getSex()+"—age:"+((Memento) momI).getAge());
    }

    public int getName() {
        return name;
    }

    public void setName(string name) {
        this.name = name;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(string sex) {
        this.sex = sex;
    }        

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    private class Memento implements MemotoI {
        private string name;


        private string sex;

        private int age;

        public Memento(string name,string sex,int age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
            System.out.println("备忘录,当前保存状态:name==" + name + "—sex:" + sex + "—age:" + age);
        }

        public int getName() {
            return name;
        }

        public void setName(string name) {
            this.name = name;
        }

        public int getSex() {
            return sex;
        }

        public void setSex(string sex) {
            this.sex = sex;
        }        

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
           this.age = age;
        }
    }
}

 

3、管理者

public class Caretaker {
    private MemotoI memento;

    /**
     * 备忘录的取值方法
     */
    public MemotoIF getMemento() {
        return this.memento;
    }

    /**
     * 备忘录的赋值方法
     */
    public void saveMemento(MemotoI memento) {
        this.memento = memento;
    }
}

 

4、demo代码

string name = “nino”;
        string sex = “男”;
        int age = 3;

        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setName(name);
        originator.setSex(sex);
        originator.setAge(age);

        /**
         * 创建备忘录对象的 缓存起来
         */
        caretaker.saveMemento(originator.creatMementoObject());

        /*
         * 进行设置重新还原
         */
        originator.setAge(5);
        System.out.println(" 发起人更改状态:" + originator.getAge());
        originator.restoreMemento(caretaker.getMemento());