博客信息

备忘录模式Memento(行为模式)

发布时间:『 2019-03-29 23:58』  博客类别:23种设计模式  阅读(782)
  • 术语

    Memento:备忘录 originator:发起者 Caretaker:守护者

UML类图

小李飞刀_设计模式



  • 角色

    originator 待保存状态的对象 ~ Hero Memento 备忘录对象 Caretaker 存放备忘录对象的容器;可以是List、Map、或者单个Memento对象 可以保存多个 originator 对象的不同时间的状态

  • 案例

    需求:游戏人物大战后状态恢复

  • 情况1:为一个对象保留一个状态

  package com.javaxl.design.memento.one;
 
/**
  * @author 小李飞刀
  * @site www.javaxl.com
  * @company
  * @create  2020-02-24 22:16
  */
public class Hero {
//   需要存档的属性:这里用一个state属性来表示,实际需要存档的属性可能会有很多
    private String state;
 
    public Hero(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
 
//   将当前Hero对象实例进行备份
    public HeroMemento saveHero(){
        return new HeroMemento(this.state);
    }
 
//   恢复上一个英雄状态
    public void getMemento(HeroMemento heroMemento){
        this.state = heroMemento.getState();
    }
 
}
 
 
public class HeroMemento {
    private String state;
 
    public HeroMemento(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
}
 
 
public class Caretaker {
    private HeroMemento heroMemento;
 
    public HeroMemento getHeroMemento() {
        return heroMemento;
    }
 
    public void setHeroMemento(HeroMemento heroMemento) {
        this.heroMemento = heroMemento;
    }
}
 
 
public class Client {
    public static void main(String[] args) {
        Hero hero = new Hero("状态1,满血状态");
        Caretaker caretaker = new Caretaker();
 
        caretaker.setHeroMemento(hero.saveHero());
        hero.setState("状态2:状态下滑");
        System.out.println("当前的状态==============="+hero.getState());
//       hero.getMemento(caretaker.getHeroMemento());
//       System.out.println("当前的状态==============="+hero.getState());
 
        caretaker.setHeroMemento(hero.saveHero());
        hero.setState("状态3:残血状态");
        hero.getMemento(caretaker.getHeroMemento());
        System.out.println("当前的状态==============="+hero.getState());
 
        caretaker.setHeroMemento(hero.saveHero());
        hero.setState("状态4:临死状态");
        caretaker.setHeroMemento(hero.saveHero());
 
    }
}

  • 情况2:为一个对象保留多个状态

  public class Hero {
//   需要存档的属性:这里用一个state属性来表示,实际需要存档的属性可能会有很多
    private String state;
 
    public Hero(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
 
//   将当前Hero对象实例进行备份
    public HeroMemento saveHero(){
        return new HeroMemento(this.state);
    }
 
//   恢复某一个英雄状态
    public void getMemento(Caretaker caretaker,int no){
        this.state = caretaker.getMemento(no).getState();
    }
 
}
 
 
public class HeroMemento {
    private String state;
 
    public HeroMemento(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
 
    public void setState(String state) {
        this.state = state;
    }
}
 
 
public class Caretaker {
    private List<HeroMemento> heroMementos = new ArrayList<>();
 
    public void addMemento(HeroMemento memento){
        heroMementos.add(memento);
    }
 
    public HeroMemento getMemento(int no){
        return heroMementos.get(no);
    }
 
}
 
 
public class Client {
    public static void main(String[] args) {
        Hero hero = new Hero("状态1,满血状态");
        Caretaker caretaker = new Caretaker();
        caretaker.addMemento(hero.saveHero());
 
        hero.setState("状态2:状态下滑");
 
        hero.setState("状态3:残血状态");
        caretaker.addMemento(hero.saveHero());
 
        hero.setState("状态4:临死状态");
        caretaker.addMemento(hero.saveHero());
 
        hero.setState("状态5:死亡状态");
 
//       上面备份了1、3、4状态,我来恢复看看
        System.out.println("当前的状态==============="+hero.getState());
        hero.getMemento(caretaker,0);
        System.out.println("回复到状态1==============="+hero.getState());
        hero.getMemento(caretaker,1);
        System.out.println("回复到状态3==============="+hero.getState());
        hero.getMemento(caretaker,2);
        System.out.println("回复到状态4==============="+hero.getState());
 
    }
}

  • 情况3:为多个对象保留一个状态

    public class Caretaker {
      private HashMap<Originator ,Memento> mementos = new HashMap();
    }

    略...

  • 情况4:为多个对象保留多个对象

    public class Caretaker {
      private HashMap<Originator , List<Memento>> mementos = new HashMap();
    }

    略...

  • 注意事项和细节

    • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态

    • 实现了信息的封装,使得用户不需要关心状态的保存细节

注意:如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存

  • 应用 事务回滚 游戏的存档 Selenium动态解析资源树


总结

  备忘录模式也是一种比较常用的模式用来保存对象的部分用于恢复的信息,和原型模式有着本质的区别,广泛运用在快照功能之中,另外我们知道了宽接口和窄接口,这里的接口就是指的方法,没有其他意思,以及类的可见性。同样的使用备忘录模式可以使得程序可以组件化,比如打算多次撤销当前的状态,以及不仅可以撤销而且可以将当前的状态保存到文件之中的时候,


over......


关键字:     设计模式  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有