Vedi il codice qui sotto:
public sealed class UKCurrency : ICurrency
{
private static readonly int _decimalPlaces=2;
private static readonly decimal[] _denominations = new decimal[] {
50.00M, 20.00M, 10.00M,
5.00M, 2.00M, 1.00M,
0.50M, 0.20M, 0.10M,
0.05M, 0.02M, 0.01M,
};
public IEnumerable<decimal> Denominations
{
get { foreach (var denomination in _denominations) yield return denomination; }
}
}
public sealed class DenominationCounter
{
private readonly decimal _cost;
public decimal Cost
{
get { return _cost; }
}
public ICurrency Currency
{
get { return _currency; }
}
public DenominationCounter(decimal cost, ICurrency currency)
{
if (currency == null)
throw new ArgumentNullException("Currency cannot be null", "ICurrency");
if (cost < 0)
throw new ArgumentException("Cost cannot be negative", "Cost");
if (decimal.Round(cost, currency.DecimalPlaces) != cost)
throw new ArgumentException(string.Concat("Cost has too many decimal places. It should only have: ", currency.DecimalPlaces), "Cost");
_cost = cost;
_currency = currency;
}
public IEnumerable<System.Collections.Generic.KeyValuePair<decimal, int>> CalculateDenominations()
{
var target = _cost;
foreach (var denomination in _currency.AvailableDenominations)
{
var numberRequired = target / denomination;
if (numberRequired >= 1)
{
int quantity = (int)Math.Floor(numberRequired);
yield return new KeyValuePair<decimal, int>(denomination, quantity);
target = target - (quantity * denomination);
}
}
}
}
Il costruttore DenominationCounter genera un'eccezione se il costo ha il numero sbagliato di cifre decimali.
Si noti che la classe UKCurrency viene utilizzata per convalidare DenominationCounter come mostrato di seguito:
if (decimal.Round(cost, currency.DecimalPlaces) != cost)
È normale procedere con la convalida in questo modo:
1) Un membro Value Objects viene utilizzato per convalidare un'entità
2) Un membro Value Objects viene utilizzato per convalidare un altro oggetto valore
Lo chiedo perché non ho mai visto una convalida approcciata in questo modo e sto cercando di seguire il principio del minimo stupore in questi giorni.