zoukankan      html  css  js  c++  java
  • js备忘录模式

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

    • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。
    • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
    • 使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来,当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

    介绍完备忘录模式的定义之后,下面具体看看备忘录模式的结构图:

    备忘录模式中主要有三类角色:

    • 发起人角色:记录当前时刻的内部状态,负责创建和恢复备忘录数据。
    • 备忘录角色:负责存储发起人对象的内部状态,在进行恢复时提供给发起人需要的状态。
    • 管理者角色:负责保存备忘录对象。

    C#备忘录模式-单个存储点:

    namespace 备忘录模式_单个存储点
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                //大战Boss前
                GameRole lixiaoyao = new GameRole();
                lixiaoyao.GetInitState();
                lixiaoyao.StateDisplay();
    
                //保存进度
                RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
                stateAdmin.Memento = lixiaoyao.SaveState();
    
                //大战Boss时,损耗严重
                lixiaoyao.Fight();
                lixiaoyao.StateDisplay();
    
                //恢复之前状态
                lixiaoyao.RecoveryState(stateAdmin.Memento);
    
                lixiaoyao.StateDisplay();
    
    
                Console.Read();
    
            }
        }
    
        class GameRole
        {
            //生命力
            private int vit;
            public int Vitality
            {
                get { return vit; }
                set { vit = value; }
            }
    
            //攻击力
            private int atk;
            public int Attack
            {
                get { return atk; }
                set { atk = value; }
            }
    
            //防御力
            private int def;
            public int Defense
            {
                get { return def; }
                set { def = value; }
            }
    
            //状态显示
            public void StateDisplay()
            {
                Console.WriteLine("角色当前状态:");
                Console.WriteLine("体力:{0}", this.vit);
                Console.WriteLine("攻击力:{0}", this.atk);
                Console.WriteLine("防御力:{0}", this.def);
                Console.WriteLine("");
            }
    
            //保存角色状态
            public RoleStateMemento SaveState()
            {
                return (new RoleStateMemento(vit, atk, def));
            }
    
            //恢复角色状态
            public void RecoveryState(RoleStateMemento memento)
            {
                this.vit = memento.Vitality;
                this.atk = memento.Attack;
                this.def = memento.Defense;
            }
    
    
            //获得初始状态
            public void GetInitState()
            {
                this.vit = 100;
                this.atk = 100;
                this.def = 100;
            }
    
            //战斗
            public void Fight()
            {
                this.vit = 0;
                this.atk = 0;
                this.def = 0;
            }
        }
    
        //角色状态存储箱
        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 Vitality
            {
                get { return vit; }
                set { vit = value; }
            }
    
            //攻击力
            public int Attack
            {
                get { return atk; }
                set { atk = value; }
            }
    
            //防御力
            public int Defense
            {
                get { return def; }
                set { def = value; }
            }
        }
    
        //角色状态管理者
        class RoleStateCaretaker
        {
            private RoleStateMemento memento;
    
            public RoleStateMemento Memento
            {
                get { return memento; }
                set { memento = value; }
            }
        }
    }

    C#备忘录模式-多个存储点:

    namespace 备忘录模式_多个存储点
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                //大战Boss前
                GameRole lixiaoyao = new GameRole();
                lixiaoyao.GetInitState();
                lixiaoyao.StateDisplay();
    
                //保存进度
                RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
                stateAdmin.MementoDic.Add(DateTime.Now.ToString(), lixiaoyao.SaveState());
    
                //大战Boss时,损耗严重
                lixiaoyao.Fight1();
                lixiaoyao.StateDisplay();
    
                //保存进度
                Thread.Sleep(1000);
                stateAdmin.MementoDic.Add(DateTime.Now.ToString(), lixiaoyao.SaveState());
    
                //大战Boss时,损耗严重
                lixiaoyao.Fight2();
                lixiaoyao.StateDisplay();
    
                //恢复之前状态
                Console.WriteLine("-------恢复联系人列表,请从以下列表选择恢复的日期------");
                var keyCollection = stateAdmin.MementoDic.Keys;
                foreach (string k in keyCollection)
                {
                    Console.WriteLine("Key = {0}", k);
                }
                while (true)
                {
                    Console.Write("请输入数字,按窗口的关闭键退出:");
    
                    int index = -1;
                    try
                    {
                        index = Int32.Parse(Console.ReadLine());
                    }
                    catch
                    {
                        Console.WriteLine("输入的格式错误");
                        continue;
                    }
    
                    RoleStateMemento memento = null;
                    if (index < keyCollection.Count && stateAdmin.MementoDic.TryGetValue(keyCollection.ElementAt(index), out memento))
                    {
                        lixiaoyao.RecoveryState(memento);
                        lixiaoyao.StateDisplay();
                    }
                    else
                    {
                        Console.WriteLine("输入的索引大于集合长度!");
                    }
                }     
            }
        }
    
        class GameRole
        {
            //生命力
            private int vit;
            public int Vitality
            {
                get { return vit; }
                set { vit = value; }
            }
    
            //攻击力
            private int atk;
            public int Attack
            {
                get { return atk; }
                set { atk = value; }
            }
    
            //防御力
            private int def;
            public int Defense
            {
                get { return def; }
                set { def = value; }
            }
    
            //状态显示
            public void StateDisplay()
            {
                Console.WriteLine("角色当前状态:");
                Console.WriteLine("体力:{0}", this.vit);
                Console.WriteLine("攻击力:{0}", this.atk);
                Console.WriteLine("防御力:{0}", this.def);
                Console.WriteLine("");
            }
    
            //保存角色状态
            public RoleStateMemento SaveState()
            {
                return (new RoleStateMemento(vit, atk, def));
            }
    
            //恢复角色状态
            public void RecoveryState(RoleStateMemento memento)
            {
                this.vit = memento.Vitality;
                this.atk = memento.Attack;
                this.def = memento.Defense;
            }
    
    
            //获得初始状态
            public void GetInitState()
            {
                this.vit = 100;
                this.atk = 100;
                this.def = 100;
            }
    
            //战斗
            public void Fight1()
            {
                this.vit = 50;
                this.atk = 50;
                this.def = 50;
            }
            public void Fight2()
            {
                this.vit = 0;
                this.atk = 0;
                this.def = 0;
            }
        }
    
        //角色状态存储箱
        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 Vitality
            {
                get { return vit; }
                set { vit = value; }
            }
    
            //攻击力
            public int Attack
            {
                get { return atk; }
                set { atk = value; }
            }
    
            //防御力
            public int Defense
            {
                get { return def; }
                set { def = value; }
            }
        }
    
        //角色状态管理者
        class RoleStateCaretaker
        {
            // 使用多个备忘录来存储多个备份点
            private Dictionary<string, RoleStateMemento> mementoDic;
            public Dictionary<string, RoleStateMemento> MementoDic
            {
                get { return mementoDic; }
                set { mementoDic = value; }
            }
            public RoleStateCaretaker()
            {
                MementoDic = new Dictionary<string, RoleStateMemento>();
            }
        }
    }

    js的备忘录模式-单个存储点:

    var GameRole = function(){
    
            //角色状态存储箱
            var roleStateMemento = {};
            
            this.getMemento = function(){
                return roleStateMemento;
            };
    
            this.setMemento = function(memento){
                roleStateMemento = memento;
            };
    
            this.getInitState();
        };
        //状态显示
        GameRole.prototype.stateDisplay = function(){
            console.log('角色当前状态:');
            console.log('体力:' + this.vitality);
            console.log('攻击力:' + this.attack);
            console.log('防御力:' + this.defense);
        };
        //保存角色状态
        GameRole.prototype.saveState = function(){
            this.setMemento({
                vitality:this.vitality,
                attack:this.attack,
                defense:this.defense
            });
        };
        //恢复角色状态
        GameRole.prototype.recoveryState = function(){
            var memento = this.getMemento();
            this.vitality = memento.vitality;
            this.attack = memento.attack;
            this.defense = memento.defense;
        };
        //获得初始状态
        GameRole.prototype.getInitState = function(){
            this.vitality = 100;
            this.attack = 100;
            this.defense = 100;
        };
        //战斗
        GameRole.prototype.fight = function(){
            this.vitality = 0;
            this.attack = 0;
            this.defense = 0;
        };
    
    
        //调用:
        //
        //大战Boss前
        var gr = new GameRole();
        gr.stateDisplay();
    
        //保存进度
        gr.saveState();
    
        //大战Boss时,损耗严重
        gr.fight();
        gr.stateDisplay();
    
        //恢复之前状态
        gr.recoveryState();
        gr.stateDisplay();

    js的备忘录模式-多个存储点:

    var GameRole = function(){
    
            //角色状态存储箱
            var roleStateMemento = {};
    
            this.getMemento = function(key){
                if(key)
                    return roleStateMemento[key];
                else
                    return roleStateMemento;
            };
    
            this.setMemento = function(key,memento){
                roleStateMemento[key] = memento;
            };
    
            this.getInitState();
        };
        //状态显示
        GameRole.prototype.stateDisplay = function(){
            console.log('角色当前状态:');
            console.log('体力:' + this.vitality);
            console.log('攻击力:' + this.attack);
            console.log('防御力:' + this.defense);
        };
        //保存角色状态
        GameRole.prototype.saveState = function(key){
            this.setMemento(key,{
                vitality:this.vitality,
                attack:this.attack,
                defense:this.defense
            });
        };
        //恢复角色状态
        GameRole.prototype.recoveryState = function(key){
            var memento = this.getMemento(key);
            this.vitality = memento.vitality;
            this.attack = memento.attack;
            this.defense = memento.defense;
        };
        //获得初始状态
        GameRole.prototype.getInitState = function(){
            this.vitality = 100;
            this.attack = 100;
            this.defense = 100;
        };
        //战斗
        GameRole.prototype.fight1 = function(){
            this.vitality = 50;
            this.attack = 50;
            this.defense = 50;
        };
        GameRole.prototype.fight2 = function(){
            this.vitality = 0;
            this.attack = 0;
            this.defense = 0;
        };
    
    
        //调用:
        //
        //大战Boss前
        var gr = new GameRole();
        gr.stateDisplay();
    
        //保存进度
        gr.saveState(new Date().getTime());
    
        //大战Boss时,损耗严重
        gr.fight1();
        gr.stateDisplay();
    
    
        setTimeout(function(){
    
            //保存进度
            gr.saveState(new Date().getTime());
    
            //大战Boss时,损耗严重
            gr.fight2();
            gr.stateDisplay();
    
            var mementos = gr.getMemento();
            for(var key in mementos){
                console.log('key = ' + key);
    
                //恢复之前状态
                gr.recoveryState(key);
                gr.stateDisplay();
            }
    
        },1000);

    总结

    备忘录模式主要思想是——利用备忘录对象来对保存发起人的内部状态,当发起人需要恢复原来状态时,再从备忘录对象中进行获取,如果系统需要提供回滚操作时,使用备忘录模式非常合适。例如文本编辑器的Ctrl+Z撤销操作的实现,数据库中事务操作。

  • 相关阅读:
    ABP官方文档翻译 3.4 领域服务
    ABP官方文档翻译 3.3 仓储
    ABP官方文档翻译 3.2 值对象
    ABP官方文档翻译 3.1 实体
    ABP官方文档翻译 2.7 对象到对象的映射
    ABP官方文档翻译 2.6 定时
    bootstrap 源码中部分不了解的css属性
    vue 父组件调用子组件事件/子组件调用父组件方法
    js性能优化问题学习笔记
    js递归性能影响及解决方案
  • 原文地址:https://www.cnblogs.com/gongshunkai/p/6626112.html
Copyright © 2011-2022 走看看