Skip to content

Instantly share code, notes, and snippets.

@johncoder
Created November 5, 2012 16:11
Show Gist options
  • Save johncoder/4018032 to your computer and use it in GitHub Desktop.
Save johncoder/4018032 to your computer and use it in GitHub Desktop.
Laugh & Learn - Pick Your Poison
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
public class Program
{
public static void Main()
{
var ledgerKeeper = new LedgerKeeper();
ledgerKeeper.Add(new[] { 1m, 2m, -3m, 4m });
var ledger = ledgerKeeper.GetLedger();
Console.WriteLine(ledger.Balance);
//ledgerKeeper.Add(new[] { 1m, 2m, -3m, 4m });
ledger.Add(1m);
ledger.Add(2m);
ledger.Add(-3m);
ledger.Add(4m);
ledgerKeeper.Commit(ledger);
ledger = ledgerKeeper.GetLedger();
Console.WriteLine(ledger.Balance);
Console.ReadKey(true);
}
public class Ledger
{
public decimal Balance { get; protected set; }
private List<decimal> newTransactions = new List<decimal>();
public IEnumerable<decimal> GetNewTransactions()
{
return this.newTransactions.ToArray();
}
public Ledger(LedgerMemento memento)
{
this.Balance = memento.Balance;
}
public Ledger()
{
this.Balance = 0m;
}
public void Add(decimal transaction)
{
// we could optionally validate the transaction
// i.e. - don't allow a negative balance; throw instead
this.newTransactions.Add(transaction);
this.Apply(transaction);
}
private void Apply(decimal transaction)
{
this.Balance += transaction;
}
public void Calculate(IEnumerable<decimal> history)
{
foreach (var d in history)
{
this.Apply(d);
}
}
public LedgerMemento CreateMemento()
{
return new LedgerMemento(this.Balance);
}
}
public class LedgerKeeper
{
private List<decimal> history = new List<decimal>();
private LedgerMemento memento;
private int mementoIndex;
public void Add(IEnumerable<decimal> newItems)
{
history.AddRange(newItems);
}
public Ledger GetLedger()
{
Ledger ledger;
if (memento != null)
{
ledger = new Ledger(memento);
ledger.Calculate(history.Skip(mementoIndex));
}
else
{
ledger = new Ledger();
ledger.Calculate(history);
}
return ledger;
}
public void Commit(Ledger ledger)
{
this.history.AddRange(ledger.GetNewTransactions());
this.memento = ledger.CreateMemento();
this.mementoIndex = this.history.Count();
}
}
public class LedgerMemento
{
public decimal Balance { get; protected set; }
public LedgerMemento(decimal balance)
{
this.Balance = balance;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment