Skip to content

Instantly share code, notes, and snippets.

@asarnaout
Created July 6, 2018 17:42
Show Gist options
  • Save asarnaout/70ff87938104f7f4c01d03cab3547e6a to your computer and use it in GitHub Desktop.
Save asarnaout/70ff87938104f7f4c01d03cab3547e6a to your computer and use it in GitHub Desktop.
Memento Design Pattern
public class Program
{
public static void Main(string[] args)
{
var account = new Account {
Id = 1,
Verified = false,
Credit = 10,
Notes = "None"
};
var accountCareTaker = new AccountCareTaker(account);
accountCareTaker.Persist(CheckPoint.Created);
VerifyAccount(account);
accountCareTaker.Persist(CheckPoint.Verified);
DeleteAccount(account);
accountCareTaker.Persist(CheckPoint.Deleted);
Console.WriteLine("Restoring to the creation point");
accountCareTaker.Restore(CheckPoint.Created);
Console.WriteLine($"Notes: {account.Notes}"); //Prints "None"
Console.WriteLine($"Credit: {account.Credit}"); //Prints 10
Console.WriteLine("\nRestoring to the verification point");
accountCareTaker.Restore(CheckPoint.Verified);
Console.WriteLine($"Notes: {account.Notes}"); //Prints "Verified"
Console.WriteLine($"Credit: {account.Credit}"); //Prints 20
Console.WriteLine("\nRestoring to the deletion point");
accountCareTaker.Restore(CheckPoint.Deleted);
Console.WriteLine($"Notes: {account.Notes}"); //Prints "Deleted"
Console.WriteLine($"Credit: {account.Credit}"); //Prints 0
}
public static void VerifyAccount(Account account)
{
account.Verified = true;
account.Credit *= 2;
account.Notes = "Verified";
}
public static void DeleteAccount(Account account)
{
account.Verified = false;
account.Credit = 0;
account.Notes = "Deleted";
}
}
public class Account //The Originator
{
public int Id { get; set; }
public bool Verified { get; set; }
public int Credit { get; set; }
public string Notes { get; set; }
public AccountMemento GetMemento()
{
return new AccountMemento {
AccountState = $"{Id}-{Verified}-{Credit}-{Notes}"
};
}
public void RestoreFromMemento(AccountMemento memento)
{
var state = memento.AccountState.Split('-').ToList();
Id = int.Parse(state[0]);
Verified = bool.Parse(state[1]);
Credit = int.Parse(state[2]);
Notes = state[3];
}
}
public class AccountMemento { // The memento holds the state of the originator
public string AccountState { get; set; }
}
public class AccountCareTaker //The CareTaker acts as the safe keeper for the mementos
{
private readonly IDictionary<CheckPoint, AccountMemento> _accountMementos;
private readonly Account _account;
public AccountCareTaker(Account account)
{
_accountMementos = new Dictionary<CheckPoint, AccountMemento>();
_account = account;
}
public void Restore(CheckPoint checkPoint)
{
if(_accountMementos.TryGetValue(checkPoint, out var result))
{
_account.RestoreFromMemento(result);
return;
}
throw new Exception("Checkpoint not found...");
}
public void Persist(CheckPoint checkPoint) {
if(_accountMementos.TryGetValue(checkPoint, out var _))
{
throw new Exception("Checkpoint already exists");
}
_accountMementos.Add(checkPoint, _account.GetMemento());
}
}
public enum CheckPoint {
Created = 1,
Verified = 2,
Deleted = 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment