关于纪念品的一些解释

时间:2013-10-22 17:04:03

标签: c# undo memento

我已经检查了每一个地方,并阅读了无数的文章。我甚至去了一些寻找答案的中文论坛。问题是我无法完全理解c#memento模式。不同的文章显示了不同的方式,我无法正确理解它。大多数文章只显示简单的东西,如字符串纪念品。我试图了解如何执行撤销功能并需要帮助,还有,如何在公共局部类上执行撤销功能?,我只需要一个显示公共部分类纪念品的小例子。提前谢谢。

1 个答案:

答案 0 :(得分:1)

基本上,纪念品是一种保存和恢复对象状态的方法。但它有点超出了:它是一种保留封装的方式。因此,如果要保存其状态的对象具有一些私有成员,则memento模式是一种能够以有限的方式访问这些成员的方式。

举一个例子,假设我们有一个2D角色围着地图做醉酒走路:

public class Sprite
{
    private double _x = 0, _y = 0;
    public void Run()
    {
        var random = new byte[2];
        new Random().NextBytes(random);
        _x += (double)random[0];
        _y += (double)random[1];
    }

    public void Render()
    {
        Console.WriteLine("({0}, {1})", _x, _y);
    }
}

假设我们不希望将x和y公开为公共成员,但我们希望能够保存对象的状态。然后我们可以创建一个封装对象状态的memento类:

public class SpriteMemento
{
    public double X { get; set; }
    public double Y { get; set; }
}

Sprite类可以接受memento对象来恢复其状态,并提供一个保存:

public class Sprite
{
    // ...

    public SpriteMemento Memento
    {
        get { return new SpriteMemento { X = _x, Y = _y }; }
    }

    public void Restore(SpriteMemento memento)
    {
        if (memento == null)
            return; 

        _x = memento.X;
        _y = memento.Y;
    }
}

现在,假设我们有另一个控制运行的类。我们现在可以让这个类提供“撤消”功能:

static void Main(string[] args)
{
    var sprite = new Sprite();
    SpriteMemento state = null;
    while (true)
    {
        string input = Console.ReadLine();
        if (input == "run")
            sprite.Run();
        else if (input == "save")
            state = sprite.Memento;
        else if (input == "undo")
            sprite.Restore(state);

        sprite.Render();
    }
}

就部分类而言,实际上没有区别 - 只需对上面的Sprite类进行“部分”处理,并且纪念图案仍然完好无损。

参考:Memento Design Pattern