设计模式——备忘录模式

什么是备忘录模式

备忘录模式其实类似于我们常见的游戏存档和回档,会有一个对象专门存储某个对象某个时刻的状态(即属性值),这个对象就相当于一份备忘录,在需要的时候,我们可以将对象恢复到备忘录中记录的状态

备忘录模式有三个角色:

originator

需要备份的对象

memento

保存备份的对象

caretaker

负责管理memento,这个对象只起到保存备份的作用,不能更改和查看备份,即memento对于caretaker来说是不可见的

接下来用java实现备忘录模式,备忘录模式有四种经典的实现方式,这里只介绍白箱和黑箱,尤其是黑箱,设计非常巧妙

白箱实现

白箱实现会有三个类,分别为originator、memento、caretaker

originator需要实现两个方法,一个方法返回mementor(备份)对象,一个方法根据mementor对象进行回档

originator

package memento;



/**

 *

 * @author lzy

 */

public class originator {

    private String name;

    private int age;

    private String sex;



    public originator(String name, int age, String sex) {

        this.name = name;

        this.age = age;

        this.sex = sex;

    }



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public int getAge() {

        return age;

    }



    public void setAge(int age) {

        this.age = age;

    }



    public String getSex() {

        return sex;

    }



    public void setSex(String sex) {

        this.sex = sex;

    }

    
    //创造备份对象memento
    public memento createMemento(){

        return new memento(name,age,sex);

    }

    
    //回档
    public void setMemento(memento mem){

        this.age=mem.getAge();

        this.name=mem.getName();

        this.sex=mem.getSex();

    }

    

    public void display(){

        System.out.println("Age="+age+",Name="+name+",Sex="+sex);

    }

}


memento:

memento和originator的属性相同,但是没有创造备份对象和回档的方法

package memento;

/**
 *
 * @author lzy
 */
public class memento {
    private String name;
    private int age;
    private String sex;

    public memento(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

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

caretaker:

creataker仅仅是保存对象,但在白箱实现中,通过caretaker可以知道和更改memento的值,虽然我们可以在memento不提供set方法,但是get方法是必须的(回档时需要使用),我们甚至可以自己实现一个memento,memento的封装性遭到破坏

package memento;

/**
 *
 * @author lzy
 */
public class caretaker {
    private memento mem;

    public memento getMem() {
        return mem;
    }

    public void setMem(memento mem) {
        this.mem = mem;
    }
    
}

在main方法中进行测试

package memento;

/**
 *
 * @author lzy
 */
public class main {
    public static void main(String[] args) {
        originator per=new originator("菜到怀疑人生",18,"基佬");
        caretaker tk=new caretaker();
        tk.setMem(per.createMemento());
  
        System.out.print("修改前:");
        per.display();
     
        per.setAge(100);
        System.out.print("修改后:");
        per.display();
        
        per.setMemento(tk.getMem());
        System.out.print("备份恢复后:");
        per.display();
        
        
    }
        
}

运行结果:

白箱实现虽然简单,但是memento的封装性遭到严重破坏

黑箱实现

在黑箱实现中,将memento作为originator的私有内部类,caretaker只有mementor的一个标识,这个标识为一个空接口(即没有任何方法和属性),memento会继承这个接口,空接口使caretaker无法查看mementor的值,将mementor置为私有内部类,这点最巧妙,我们无法通过originator对象来查看和更改memento的值,我们只能够通过originator提供的创造备份的方法来创造备份,不允许我们自己创建备份对象,黑箱实现克服了一系列白箱实现的缺点

mementoF:接口标识

package memorandum2;

/**
 *
 * @author lzy
 */
public interface mementoF {
    
}

originator与memento:

package memorandum2;

/**
 *
 * @author lzy
 */
public class originator {
    private int state;

    public originator(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
    
    private class memento implements mementoF{
        
        private int state;

        public memento(int state) {
            this.state = state;
        }

        public int getState() {
            return state;
        }

        public void setState(int state) {
            this.state = state;
        }
        
    }
    
    public mementoF createMemento(){
        return (mementoF)new memento(state);
    }
    
    public void retrieveMemento(mementoF mem){
        this.state=((memento)mem).getState();
    }
    
    public void display(){
       System.out.println("state="+state);
    }
}

caretaker:

package memorandum2;

/**
 *
 * @author lzy
 */
public class caretaker {
    private mementoF mem;
   

    public mementoF getMemento() {
        return mem;
    }

    public void setMemento(mementoF mem) {
        this.mem = mem;
    }
    
}

主函数就不写了,效果和白箱实现是一样的,但是封装性却进一步提高

猜你喜欢

转载自blog.csdn.net/dhaiuda/article/details/81077210