备忘录模式

作者: leisurexi | 来源:发表于2019-05-26 15:17 被阅读18次

    备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

    模式定义

     所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将这个对象恢复到原先保存的状态。

    模式结构

    结构图

    备忘录模式主要包含以下几个角色:

    Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复状态。Originator可根据需求决定Memento存储Originator的哪些内部状态。

    Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。

    Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

    备忘录基本代码

     发起人(Originator)类

    public class Originator {
    
        //需要保存的属性
        private String state;
    
        //创建备忘录,将当前需要保存的信息导入并实例化出一个Memento对象
        public Memento createMemento() {
            return new Memento(state);
        }
    
        //恢复备忘录,将Memento导入并将相关数据恢复
        public void setMemento(Memento memento) {
            this.state = memento.getState();
        }
    
        //显示数据
        public void show() {
            System.out.println("state = " + state);
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    }
    

     备忘录(Memento)类

    public class Memento {
    
        private String state;
    
        //构造方法,将相关数据导入
        public Memento(String state) {
            this.state = state;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    }
    

     管理者(Caretaker)类

    public class Caretaker {
    
        private Memento memento;
    
        public Memento getMemento() {
            return memento;
        }
    
        public void setMemento(Memento memento) {
            this.memento = memento;
        }
    }
    

     客户端程序

    public class Client {
    
        public static void main(String[] args) {
            Originator originator = new Originator();
            originator.setState("On");
            originator.show();
    
            Caretaker caretaker = new Caretaker();
            caretaker.setMemento(originator.createMemento());
    
            originator.setState("Off");
            originator.show();
    
            originator.setMemento(caretaker.getMemento());
            originator.show();
    
        }
    
    }
    

     运行结果

    state = On
    state = Off
    state = On
    

    模式实现

     实现场景:游戏中的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗之前。

     代码结构图

    结构图

     游戏角色类

    public class GameRole {
    
        private int vit; //生命力
        private int atk; //攻击力
        private int def; //防御力
    
        //初始化状态
        public void initState() {
            this.vit = 100;
            this.atk = 100;
            this.def = 100;
        }
    
        //战斗
        public void fight() {
            this.vit = 0;
            this.atk = 0;
            this.def = 0;
        }
    
        //保存角色状态
        public RoleStateMemento saveState() {
            return new RoleStateMemento(vit, atk, def);
        }
    
        //回复角色状态
        public void recoverState(RoleStateMemento roleStateMemento) {
            this.vit = roleStateMemento.getVit();
            this.atk = roleStateMemento.getAtk();
            this.def = roleStateMemento.getDef();
        }
    
        public void stateDisplay() {
            System.out.println("角色生命力:" + vit);
            System.out.println("角色攻击力:" + atk);
            System.out.println("角色防御力:" + def);
    
        }
    
        public int getVit() {
            return vit;
        }
    
        public void setVit(int vit) {
            this.vit = vit;
        }
    
        public int getAtk() {
            return atk;
        }
    
        public void setAtk(int atk) {
            this.atk = atk;
        }
    
        public int getDef() {
            return def;
        }
    
        public void setDef(int def) {
            this.def = def;
        }
    }
    

     游戏状态存储类

    public class RoleStateMemento {
    
        private int vit;
        private int atk;
        private int def;
    
        public RoleStateMemento(int vit, int atk, int def) {
            this.vit = vit;
            this.atk = atk;
            this.def = def;
        }
    
        public int getVit() {
            return vit;
        }
    
        public void setVit(int vit) {
            this.vit = vit;
        }
    
        public int getAtk() {
            return atk;
        }
    
        public void setAtk(int atk) {
            this.atk = atk;
        }
    
        public int getDef() {
            return def;
        }
    
        public void setDef(int def) {
            this.def = def;
        }
    }
    

     角色状态管理者类

    public class RoleStateCaretaker {
    
        private RoleStateMemento roleStateMemento;
    
        public RoleStateMemento getRoleStateMemento() {
            return roleStateMemento;
        }
    
        public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
            this.roleStateMemento = roleStateMemento;
        }
    }
    

     客户端程序

    public class Client {
    
        public static void main(String[] args) {
    
            System.out.println("------------大战Boss前------------");
            //大战Boss前
            GameRole gameRole = new GameRole();
            gameRole.initState();
            gameRole.stateDisplay();
    
            //保存进度
            RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
            roleStateCaretaker.setRoleStateMemento(gameRole.saveState());
            System.out.println("------------大战Boss后------------");
            //大战Boss时,损耗严重
            gameRole.fight();
            gameRole.stateDisplay();
            System.out.println("------------恢复之前状态------------");
            //恢复之前状态
            gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
            gameRole.stateDisplay();
    
        }
    
    }
    

     运行结果

    ------------大战Boss前------------
    角色生命力:100
    角色攻击力:100
    角色防御力:100
    ------------大战Boss后------------
    角色生命力:0
    角色攻击力:0
    角色防御力:0
    ------------恢复之前状态------------
    角色生命力:100
    角色攻击力:100
    角色防御力:100
    

    模式的优缺点

    优点

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

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

    缺点

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

    模式适用场景

     很多时候我们总是需要记录一个对象的内部状态,这样做的目的是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。

    文章作者:leisurexi

    新博客地址:https://leisurexi.github.io

    许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

    相关文章

      网友评论

        本文标题:备忘录模式

        本文链接:https://www.haomeiwen.com/subject/bszxtctx.html