页首HTML代码

Y先生的小屋

导航

行为型模式之备忘录模式

概述

备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,当前很多软件都提供了撤销(Undo)操作,其中就使用了备忘录模式。

定义

备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。

实现

原发器

    /// <summary>
    /// 象棋棋子类:原发器
    /// </summary>
    public class Chessman
    {
        public string Label { get; set; }
        public int x { get; set; }
        public int y { get; set; }

        public Chessman(string label, int x, int y)
        {
            this.Label = label;
            this.x = x;
            this.y = y;
        }

        /// <summary>
        /// 保存当前状态
        /// </summary>
        /// <returns></returns>
        public ChessmanMemento Save()
        {
            return new ChessmanMemento(this.Label, this.x, this.y);
        }

        /// <summary>
        /// 恢复到某个指定状态
        /// </summary>
        /// <param name="memento"></param>
        public void Restore(List<ChessmanMemento> mementos, int retreatStep)
        {
            ChessmanMemento memento;
            if (retreatStep >= mementos.Count)
                memento = mementos.First();
            else
                memento = mementos[mementos.Count() - 1 - retreatStep];
            this.Label = memento.Label;
            this.x = memento.x;
            this.y = memento.y;
        }
    }

备忘录

    /// <summary>
    /// 象棋棋子备忘录类:备忘录
    /// </summary>
    public class ChessmanMemento
    {
        public string Label { get; set; }
        public int x { get; set; }
        public int y { get; set; }

        public ChessmanMemento(string label, int x, int y)
        {
            this.Label = label;
            this.x = x;
            this.y = y;
        }
    }

管理者

    /// <summary>
    /// 象棋棋子备忘录管理类:负责人
    /// </summary>
    public class MementoCaretaker
    {
        private List<ChessmanMemento> mementos = new List<ChessmanMemento>();

        public List<ChessmanMemento> GetMemento()
        {
            return mementos;
        }

        public void AddMemento(ChessmanMemento memento)
        {
            mementos.Add(memento);
        }
    }

客户端

    class Program
    {
        static void Main(string[] args)
        {
            //备忘录
            MementoCaretaker mc = new MementoCaretaker();
            //象棋
            Chessman chess = new Chessman("", 1, 1);
            display(chess);
            mc.AddMemento(chess.Save()); //保存状态 坐标1,1    
            chess.y = 4;
            display(chess);
            mc.AddMemento(chess.Save()); //保存状态 坐标1,4 
            chess.x = 5;
            display(chess);
            mc.AddMemento(chess.Save()); //保存状态 坐标5,4
            chess.x = 7;
            chess.y = 13;
            display(chess);
            mc.AddMemento(chess.Save()); //保存状态 坐标7,13
            int retreatStep = 2;
            Console.WriteLine("******悔棋【{0}】步******", retreatStep);
            chess.Restore(mc.GetMemento(), retreatStep); //恢复状态 后退指定步数 
            display(chess);
            Console.ReadLine();
        }
        public static void display(Chessman chess)
        {
            Console.WriteLine("棋子【" + chess.Label + "】当前位置为:" + "" + chess.x + "" + "" + chess.y + "列。");
        }
    }

总结

主要优点

1、它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

2、备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

主要缺点

资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。

适用场景

1、保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。

2、防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。

 

posted on 2016-06-19 11:33  Y.Mr  阅读(140)  评论(0编辑  收藏  举报

页脚HTML代码