备忘录模式(Memento)

简介

备忘录模式,它是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。备忘录模式的作用是当角色的状态改变时,有可能这个状态无效,这时候就可以使用暂时储存起来的备忘录将状态复原。


书中实例

小菜想着,玩游戏打Boss之前还是得保存进度啊,不然挂了就费了。大鸟说:"那好吧,咱们今天就讲备忘录模式,就用保存游戏进度的例子来讲。"小菜说:"放过我吧,我还是个孩子......"

今天的例子是这样:游戏的某个场景,一游戏角色有生命力,攻击力,防御力等等数据,在打Boss前和后这些数据是不一样的。我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗前。


备忘录模式实现程序

    //游戏角色类
    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 void GetInitState()
        {
            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 RecoveryState(RoleStateMemento memento)
        {
            this.vit = memento.Vitality;
            this.atk = memento.Attack;
            this.def = memento.Defense;
        }
    }
    //角色状态储存箱类
    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 vit; }
            set { vit = value; }
        }

    }
    //角色状态管理者类
    class RoleStateCaretaker
    {
        private RoleStateMemento memento;
        public RoleStateMemento Memento
        {
            get { return memento; }
            set { memento = value; }
        }
    }
    //客户端
    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();
        }
    }


组成类图



关系介绍

发起人(Originator):负责创建一个备忘录(Memento),它依赖于备忘录类。管理者类(Caretaker)和备忘录之间是聚合关系,备忘录类拥有管理者类。


备忘录模式的构成

Originator(发起人):负责创建一个备忘录,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。

Memento(备忘录):负责存储发起人对象的内部状态,并可防止发起人以外的其他对象访问备忘录。

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


备忘录模式的优点

1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。

3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。


使用场景

1.适用于功能比较复杂的,但需要维护或记录属性历史的类。

2.如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值