设计模式:Memento--备忘录模式

备忘录模式:

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。做个图来分析一下:

 

Original类是原始类,里面有需要保存的属性value及创建一个备忘录类Mementor,用来保存value值。Memento类是备忘录类,Caretake类是存储备忘录的类(备忘录管理者),持有Memento类的实例,该模式很好理解。

角色分析:

Originator:对象,需要保存状态或者其他元素的元对象

Mementor:备忘录对象,负责记录

Caretake:守护备忘录对象,负责报错多个备忘录对象,使用集合或者map或者单个mementor,

实例代码一:


public class Original {
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Original(String value) {
        this.value = value;
    }

    //备份
    public Mementor createMementor() {
        return new Mementor(value);
    }

    //恢复备份的数据
    public void restoreMemento(Mementor mementor) {
        this.value = mementor.getValue();
    }
}

***********************************************************************************


public class Mementor {

    String value;

    public Mementor(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}


***********************************************************************************



/**
 * 备份管理者
 */

public class Storage {
    private Mementor mementor;

    public Storage(Mementor mementor) {
        this.mementor = mementor;
    }


    public Mementor getMementor() {
        return mementor;
    }

    public void setMementor(Mementor mementor) {
        this.mementor = mementor;
    }


}


***********************************************************************************

/**
 * 主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。
 *
 * Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值。
 * Memento类是备忘录类,Storage类是存储备忘录的类,持有Memento类的实例,该模式很好理解。
 */
public class MainClass {

    public static void main(String[] args) {

        String value = "aaaaa";

        Original original = new Original(value);

        System.out.println("准备开始备份,最初的值:value="+value);

        //备份数据到memetor中,存到storage中
        Mementor mementor = original.createMementor();
        Storage storage  = new Storage(mementor);
        System.out.println("已经备份完毕");

        value= "bbbbbb";
        System.out.println("修改原始值,修改后为value="+value);

        System.out.println("开始恢复原始值");
        original.restoreMemento(mementor);

        System.out.println("恢复完毕,value="+original.getValue());


//        新建原始类时,value被初始化为aaaaa,后经过修改,将value的值置为bbbbbb,最后进行恢复状态,结果成功恢复了。其实我觉得这个模式叫“备份-恢复”模式最形象。
    }
}



***********************************************************************************
测试结果

准备开始备份,最初的值:value=aaaaa
已经备份完毕
修改原始值,修改后为value=bbbbbb
开始恢复原始值
恢复完毕,value=aaaaa

实例代码二:


/**
 * 原始类
 */
public class Person {
    private String name;

    private int age;

    private String sex;

    public Person() {
    }

    public Person(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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }

    //创建备份
    public Mementor creteMementor() {
        return new Mementor(name,age,sex);
    }

    //还原
    public void setMementor(Mementor mementor) {
        this.age = mementor.getAge();
        this.name = mementor.getName();
        this.sex = mementor.getSex();
    }
}

*************************************************************************


/**
 * 备份者
 */
public class Mementor {


    private String name;

    private int age;

    private String sex;

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

    public Mementor() {
    }

    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;
    }
}


*************************************************************************



/**
 * 备份管理者
 */

public class CareTaker {
    private Mementor mementor;


    public Mementor getMementor() {
        return mementor;
    }

    public void setMementor(Mementor mementor) {
        this.mementor = mementor;
    }
}

*************************************************************************


public class MainClass {

    public static void main(String[] args) {
        Person person = new Person("zhangsan",22,"男");
        System.out.println("最初的:"+person);

        /**
         *  原始的方式备份
         */
        //保存内部状态
        Person backup = new Person();
        backup.setName(person.getName());
        backup.setAge(person.getAge());
        backup.setSex(person.getSex());

        System.out.println("备份的:"+backup);

        //修改
        person.setAge(20);
        System.out.println("修改之后的:"+person);


        //回滚还原
        person.setAge(backup.getAge());
        System.out.println("还原之后的:  "+person);

        System.out.println("*******************************");

        /**
         * 使用备忘录模式方式备份
         *
         */
        CareTaker careTaker = new CareTaker();
        //备份
        careTaker.setMementor(person.creteMementor());

        System.out.println("最初的"+person);
        person.setName("ibf");
        person.setAge(11);
        person.setSex("女");

        System.out.println("修改后:"+person);

        //还原
        person.setMementor(careTaker.getMementor());

        System.out.println("还原后的:"+person);


    }
}


*************************************************************************

测试结果

最初的:Person{name='zhangsan', age=22, sex='男'}
备份的:Person{name='zhangsan', age=22, sex='男'}
修改之后的:Person{name='zhangsan', age=20, sex='男'}
还原之后的:  Person{name='zhangsan', age=22, sex='男'}
*******************************
最初的Person{name='zhangsan', age=22, sex='男'}
修改后:Person{name='ibf', age=11, sex='女'}
还原后的:Person{name='zhangsan', age=22, sex='男'}




*************************************************************************

三、事例

原始对象Originator ,需要保存的是state属性

@Data
public class Originator {

    private String state;

    // 保存状态
    public Mementor saveStateMementor() {
        return new Mementor(state);
    }
    // 从备忘录中 恢复状态
    public void getStateFromMementor(Mementor mementor) {
        state = mementor.getState();
    }
}

备忘录对象Mementor

@Data
public class Mementor {

    private String state;

    public Mementor(String state) {
        this.state = state;
    }
}

备忘录守护者Caretaker 

public class Caretaker {
    // 维护一个可以直接用Mementor对象
    // 维护多个可以使用List<Mementor>
    // 维护多维可以使用Map<String,ArrayList<Mementor>>

    private List<Mementor> list = new ArrayList<>();

    public void add(Mementor mementor) {
        list.add(mementor);
    }

    public Mementor get(int index) {
        return list.get(index);
    }
}

客户端调用打印

public static void main(String[] args) {
        // 备忘录模式
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        // 保存当前状态
        originator.setState("状态#1 攻击力100");
        caretaker.add(originator.saveStateMementor());

        originator.setState("状态#2 攻击力80");
        caretaker.add(originator.saveStateMementor());

        originator.setState("状态#3 攻击力50");
        caretaker.add(originator.saveStateMementor());

        System.out.println("当前状态:" + originator.getState());

        //    希望恢复的状态#1 从备忘录中恢复
        originator.getStateFromMementor(caretaker.get(0));

        System.out.println("恢复到#1 状态, 当前状态是" + originator.getState());


    }

当前状态:状态#3 攻击力50
恢复到#1 状态, 当前状态是状态#1 攻击力100

四、事例

原始对象,需要保存vit和def两个属性

@Data
public class GameRole {
    // 攻击力
    private int vit;
    // 防御力
    private int def;

    // 存储到备忘录中
    public Mementor createMementor() {
        return new Mementor(vit, def);
    }

    // 从备忘录恢复数据
    public void receiveFromMementor(Mementor mementor) {
        this.vit = mementor.getVit();
        this.def = mementor.getDef();
    }

    public void display() {
        System.out.println("游戏角色当前攻击力:" + this.vit + ";防御力:" + this.def);
    }
}

备忘录对象

@Data
public class Mementor {
    // 攻击力
    private int vit;
    // 防御力
    private int def;

    public Mementor(int vit, int def) {
        this.vit = vit;
        this.def = def;
    }
}

备忘录守护者Caretake

@Data
public class Caretaker {
    //private Map<String, List<Mementor>> listMap;
    //private List<Mementor> list;

    private Mementor mementor;

}

客户端调用打印

public static void main(String[] args) {
        // 备忘录模式,配合原型模式一起使用
        // 英雄大战
        GameRole gameRole = new GameRole();
        gameRole.setVit(100);
        gameRole.setDef(100);

        System.out.println("打boos之前的状态");
        gameRole.display();

        // 将当前状态保存备忘录
        Mementor mementor = gameRole.createMementor();

        System.out.println("与boos大战后的状态");
        gameRole.setVit(30);
        gameRole.setDef(30);
        gameRole.display();

        System.out.println("大战后,使用备忘录恢复巅峰战力");
        gameRole.receiveFromMementor(mementor);

        System.out.println("恢复战力后的状态");
        gameRole.display();

    }

打boos之前的状态
游戏角色当前攻击力:100;防御力:100
与boos大战后的状态
游戏角色当前攻击力:30;防御力:30
大战后,使用备忘录恢复巅峰战力
恢复战力后的状态
游戏角色当前攻击力:100;防御力:100

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值