How does Undo work?

2019-03-29 23:22发布

How does undo work? Does it copy all the managed objects every time any of the values change? Or does it only copy the actual changes together with an information which objects were affected? Is that heavy or lightweight?

2条回答
够拽才男人
2楼-- · 2019-03-29 23:36

Here's a rough implementation to get you thinking. This handles your stack of undoable operations. (It doesn't handle redo, but that's easy to support by replacing the stack with a list and keeping track of the current item.)

public class Undoable {
    public static void Do(Action do, Action undo) {
        do();
        sUndoStack.Push(new Undoable(do, undo));
    }

    public static void Undo() {
        sUndoStack.Pop().mUndoCallback();
    }

    private Undoable(Action doCallback, undoCallback) {
        mDoCallback = doCallback;
        mUndoCallback = undoCallback;
    }

    private Action mDoCallback, mUndoCallback;

    // note: using a global stack here is lame, but works for demo purposes
    private static readonly Stack<Undoable> sUndoStack = new Stack<Undoable>();
}

To use this, let's say the user can change a value in some object like this:

public class Foo {
    public string Bar {
        get { return mBar; }
        set {
            if (mBar != value) {
                mBar = value;
            }
        }
    }

    private string mBar;
}

To make that operation undoable, we just change the setter to:

set {
    if (mBar != value) {
        string oldValue = mBar;
        Undoable.Do(() => mBar = value,
                    () => mBar = oldValue);
    }
}

Now, if you call Undoable.Undo() from anywhere in the application, your instance of Foo will restore the previous value of Bar. If Foo also raises an event when Bar changes (not shown here), the UI will also properly refresh on undo too.

查看更多
看我几分像从前
3楼-- · 2019-03-29 23:45

The 'undo' mechanism for pretty much any language that supports Object-Oriented constructs uses the Memento Design Pattern to make it happen.

查看更多
登录 后发表回答