The GoF book "Design Patterns" describes the Memento
pattern as an object encapsulating its state in a separate object. However, the book specifically describes the memento for use with a specific caretaker; in their example, a undo/redo provider.
However, this pattern, especially in C# when the Memento is made a struct
(in both the technical and conceptual senses), can provide many benefits when made a more general part of a class:
- Allow easy cloning, which makes caching, ect easier and less error prone
- Allow persistence logic to be easily and gracefully shared by different versions of model which spans multiple domains
- Display properties in a UI which would otherwise be encapsulated
- Deal with CRUD operations for otherwise encapsulated properties
- Dealing with scope envy when it is unavoidable, for example a class which governs an operation between two other classes (does a customer book a flight, or does a flight add a customer? Let's avoid this question by putting flight booking in a separate place)
- We can use the convenient object intilizer syntax without making our properties editable. Also, we avoid constructors which are bloated with arguments
- And of course, persistence of otherwise encapsulated properties
We can also use the memento as a kind of implicitly safe to serialize version of the class throughout the application.
However, you could argue, many of the above are just abusing the pattern for the purpose of circumventing language shortcomings.
For example:
public class Computer
{
public Computer(ComputerMemento state)
{
_state = state;
}
private ComputerMemento _state;
public ComputerMemento State
{
get
{
var copy = _state;
return copy;
}
}
public void DoSomeComputerThing() { }
public void DoComputerStuff() { }
public int GetSomeComputerCalculation() { }
}
public struct ComputerMomento
{
public string MachineName;
public float ProcessorSpeed;
public long AmountOfRam;
public int CPUCores;
}
The above Computer
class can now expose an editable representation of its states while still being able to certify (albeit in an easily circumventable way) that changes to its state (via its methods) are valid and supported. Basically, the consumer can select its desired level of ignorance.
Is this expanded use of what seems to be the memento pattern still the memento pattern? If not, does it have a name?
EDIT: In the above code, since struct
s are passed by value, the state is immutable by outside classes.