BatSoft.Mementos.pas

This unit contains four implementations of the Memento pattern.

I strongly suggest you read this page and look at the the demo at the same time. The demo might be too complicated and this text too focused, but I think they complement each other nicely.

Classes

These classes enable you to make backups of the states of objects, then re-apply the old states at will, and with great ease.

ClassBackup typeFields/Properties
TBackupFieldsSingle versionFieldsBest for something like OK/Cancel.
TBackupPropertiesSingle versionPropertiesFine forOK/Cancel provided that getter/setters don’t do anything unwanted.
TVersionsFieldsMulti versionFieldsBest for undo/redo.
TVersionsPropertiesMulti versionPropertiesFine for undo/redo provided that getter/setters don’t do anything unwanted.

1. Create a memento object by supplying the originator (the object that the memento is applied to). (In this example we’re editing fPerson.)

Note: An object can safely own its own memento, though normally the form used for editing the originator is what holds the memento.

fMemento := TVersionsFields.Create(fPerson);

2. Backing up the object state, and restoring the object state are simple:

fMemento.Backup;
fMemento.Restore;

3. For the TVersions… classes, you can also undo and redo, and keep track of where you are in the undo/redo sequence using the Version… properties.

fMemento.Undo;
fMemento.Redo;
fMemento.VersionNow	// Can get and set this.
fMemento.VersionMax	// Can get this.  This is updated by the Backup method.

4. See the differences.

Changes: TChanges;
fMemento.ListChanges(Changes);

Attributes

MementoDeep

Add this to fields (only fields, not properties) to go deep. Without this, the memento will only back up the object pointer.

MementoIgnore

Add this to fields or properties (depending on the memento type) to ignore comparing them.

Supported types

  • All base types.
  • Objects are compared as pointers, unless using MementoDeep, in which case the memento will make a deep copy.
  • TStrings are backed up as single strings, so objects held in the TStrings.Objects[] are ignored.
  • Contents of records and arrays is binary compared, but not what they point to (such as string contents).