设计模式(十八)备忘录模式

作者: 我犟不过你 | 来源:发表于2021-01-22 15:24 被阅读0次

    1、概述

    备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

    2、适用场景

    1)当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。
    2)对象自行创建自己的快照,不希望其他对象对其进行访问,保证安全性。

    3、实例

    有以下实例:

    有一款游戏,支持随时存档和读档。
    在打boss前,小明进行了存档:
    当前角色攻击力为1000,防御力为800,生命值为10000。
    打boss没有打过,角色属性全部清空。
    使用备忘录。
    

    创建角色:

    package com.cloud.bssp.designpatterns.memento;
    
    /**
     * 游戏角色
     * @date: 2021/1/18
     * @author weirx
     * @version 3.0
     */
    public class GameRole {
    
        /**
         * 攻击力
         */
        private Long atk;
    
        /**
         * 防御力
         */
        private Long defense;
    
        /**
         * 生命值
         */
        private Long hp;
    
    
        public GameRole(Long atk, Long defense, Long hp) {
            this.atk = atk;
            this.defense = defense;
            this.hp = hp;
        }
    
        public GameRole() {
        }
    
        public void state() {
            System.out.println("--------当前角色信息--------");
            System.out.println("攻击力:" + this.atk);
            System.out.println("防御力:" + this.defense);
            System.out.println("血量:" + this.defense);
        }
    
        public void getInstance() {
            this.atk = 1000L;
            this.defense = 800L;
            this.hp = 10000L;
        }
    
        public void fight() {
            this.atk = 0L;
            this.defense = 0L;
            this.hp = 0L;
        }
    
        public Memento save() {
            return new Memento(this.atk, this.defense, this.hp);
        }
    
        public void read(Memento memento) {
            this.atk = memento.getAtk();
            this.defense = memento.getDefense();
            this.hp = memento.getHp();
        }
    
        public Long getAtk() {
            return atk;
        }
    
        public void setAtk(Long atk) {
            this.atk = atk;
        }
    
        public Long getDefense() {
            return defense;
        }
    
        public void setDefense(Long defense) {
            this.defense = defense;
        }
    
        public Long getHp() {
            return hp;
        }
    
        public void setHp(Long hp) {
            this.hp = hp;
        }
    }
    

    创建备忘录:

    package com.cloud.bssp.designpatterns.memento;
    
    /**
     * 存档备忘录
     * @date: 2021/1/18
     * @author weirx
     * @version 3.0
     */
    public class Memento {
    
        /**
         * 攻击力
         */
        private Long atk;
    
        /**
         * 防御力
         */
        private Long defense;
    
        /**
         * 生命值
         */
        private Long hp;
    
        public Memento(Long atk, Long defense, Long hp) {
            this.atk = atk;
            this.defense = defense;
            this.hp = hp;
        }
    
        public Long getAtk() {
            return atk;
        }
    
        public void setAtk(Long atk) {
            this.atk = atk;
        }
    
        public Long getDefense() {
            return defense;
        }
    
        public void setDefense(Long defense) {
            this.defense = defense;
        }
    
        public Long getHp() {
            return hp;
        }
    
        public void setHp(Long hp) {
            this.hp = hp;
        }
    }
    

    创建管理者:

    package com.cloud.bssp.designpatterns.memento;
    
    /**
     * 管理者
     * @date: 2021/1/22
     * @author weirx
     * @version 3.0
     */
    public class Caretaker {
    
        private Memento memento;
    
        public Memento getMemento() {
            return memento;
        }
    
        public void setMemento(Memento memento) {
            this.memento = memento;
        }
    }
    

    创建测试客户端:

    package com.cloud.bssp.designpatterns.memento;
    
    /**
     * TODO
     * @date: 2021/1/22
     * @author weirx
     * @version 3.0
     */
    public class TestDemo {
    
        public static void main(String[] args) {
    
            //创建角色并初始化
            GameRole gameRole = new GameRole();
            gameRole.getInstance();
            //获取当前角色状态
            gameRole.state();
            //存档
            Caretaker caretaker = new Caretaker();
            caretaker.setMemento(gameRole.save());
            //战斗
            gameRole.fight();
            //获取角色状态
            gameRole.state();
            //读档
            gameRole.read(caretaker.getMemento());
            //获取角色状态
            gameRole.state();
        }
    }
    

    结果:

    --------当前角色信息--------
    攻击力:1000
    防御力:800
    血量:800
    --------当前角色信息--------
    攻击力:0
    防御力:0
    血量:0
    --------当前角色信息--------
    攻击力:1000
    防御力:800
    血量:800
    

    4、分析

    上面几个类的关系如下图所示:

    GameRole.png

    1)TestDemo创建了Caretaker和GameRole,并且依赖于这两个类。
    2)Caretaker则由Memento组成,依赖于Memento。
    3)GameRole创建了Memento,依赖于Memento。

    客户端不能直接去操作备忘录,需要通过管理者Caretaker。

    5、总结

    优点:
    1)你可以在不破坏对象封装情况的前提下创建对象状态快照。
    2)实现了信息的封装,使得用户不需要关心状态的保存细节。
    3)给用户提供了一种可以恢复状态的机制,可以使用能够比较方便地回到某个历史的状态。
    缺点:
    消耗资源。

    相关文章

      网友评论

        本文标题:设计模式(十八)备忘录模式

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