C#4 中的 Memento 模式是如何实现的?
备忘录模式本身看起来非常简单。我正在考虑实现与维基百科示例相同的功能,但在此之前,C# 是否有任何语言功能可以使其更易于实现或使用?
The Memento Pattern itself seems pretty straight forward. I'm considering implementing the same as the wikipedia example, but before I do are there any language features of C# that make it easier to implement or use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一个明显的功能是泛型,实现通用纪念品将允许您将其用于任何您想要的对象。
您将看到的许多示例将使用字符串(包括当前对此问题的答复中的所有字符串)作为状态,这是一个问题,因为它是 .NET 中少数不可变的类型之一。
在处理可变对象(如任何具有 setter 属性的引用类型)时,您必须记住,当您保存备忘录时,您需要创建该对象的深层副本。否则,每当您更改原始对象时,您都会更改您的纪念品。
您可以使用 protobuf-net 或 json.net 因为它们不需要像普通的 .net 序列化机制那样使用可序列化属性标记对象。
Codeproject 关于通用备忘录实现的文章很少,但它们倾向于跳过深层复制部分:
C# 中撤消-重做的通用备忘录模式
纪念品设计模式
One obvious feature would be generics, implementing an generic memento will allow you to use it for any object you want.
Many examples that you will see will use a string (including all those currently among the replies to this question) as state which is a problem since it's one of the few types in .NET which are immutable.
When dealing with mutable objects (like any reference type with a setter-property) you have to remember though that when you save the memento you need to create a deepcopy of the object. Otherwise whenever you change your original object you will change your memento.
You could do this by using a serializer like protobuf-net or json.net since they don't require you to mark your objects with serializable attribute like the normal .net serialization mechanism does.
Codeproject have few articles about generic memento implementations, but they tend to skip the deepcopy part:
Generic Memento Pattern for Undo-Redo in C#
Memento Design Pattern
我不知道有任何内置的方式来支持
Memento
模式。我看到了一些使用 .NET Mock 框架 的实现,其中实际上,会创建对象的克隆,并且可以使用数据作为字段,但我认为这是一种开销。
通常,您可能也会在撤消/重做时使用
Memento
模式。在这种情况下,撤消/重做堆栈上的数据最好尽可能少,因此自定义可撤消对象
是我所追求的。希望这有帮助。
I'm not aware of any already built-in way to support
Memento
pattern.I see a couple of implementations by using .NET Mock frameworks, where in practise a clone of the object is created and can be field with a data, but I consider it kind of overhead.
The use
Memento
patter on Undo/Redo usually, probably you too. In this case, it's better to have as less data on Undo/Redo stack as possible, so the customundoable object
is something that I would go for.Hope this helps.
有一点可以让这种模式在 C# 中的编写速度稍快一些,那就是任何状态字段都可以声明为 public readonly,因此您不需要属性或“get”方法来访问它们。
这是包含
public readonly
的直接转换。There is one thing that will make this pattern marginally quicker to write in C# and that is that any state fields can be declared as
public readonly
so you don't need properties or 'get' methods to access them.Here is a straight conversion with
public readonly
included.我发现一个使用泛型 here :
像这样使用:
正如 @Simon Skov Boisen 提到的,这仅适用于不可变数据并且需要 深层复制。
I've found one using Generics here:
Used like this:
As @Simon Skov Boisen mentions this will only work for immutable data and requires a deep copy.