Hello!
I've got this class, let's call it Refund (because that's what it's called). I want to validate some things about this Refund and the Customer it's attached to, and I want to make these validations re-orderable, because the first one that trips will be stored as the reject reason on the Refund, and also some of them are likely to be more resource-intensive than others and more likely to be tripped, so I'd like to be able to easily reorder their execution so that I could squeeze some performance out if I need to.
All of the validation methods will take a Refund object and return a boolean denoting whether the validation has passed or failed. So, I was thinking, why not make a queue (or other data structure) to hold delegates/lambdas/anonymous functions, each representing a validation method? Then, just passing the Refund into some kind of static Validate(Refund refundToValidate) method on some Validator class. This method would walk through the array of delegates, calling each in sequence, and returning false if one of them produced false.
Is this a good idea or a stupid idea? If it's a good idea, can you point me to a resource somewhere or name a pattern that I am inadvertantly implementing, so that I know I'm doing it right? If it's a stupid idea, why and what should I be doing differently?
EDIT: here's what I've got so far-
public static class Validator
{
delegate REFUNDDENIALREASONS validationHandler(BatchRefund refundToValidate);
public static List<REFUNDDENIALREASONS> ValidateRefund(BatchRefund refundToValidate)
{
List<Delegate> Validations = new List<Delegate>();
List<REFUNDDENIALREASONS> DenialReasons = new List<REFUNDDENIALREASONS>();
Validations = new List<Delegate>();
validationHandler blockHandler = ValidateBlocks;
Validations.Add(blockHandler);
validationHandler accountHandler = ValidateCustomerAccountStatus;
Validations.Add(accountHandler);
foreach (validationHandler v in Validations)
{
DenialReasons.Add(v(refundToValidate));
}
return DenialReasons;
}
public static REFUNDDENIALREASONS ValidateCustomerAccountStatus(BatchRefund refundToHandle)
{
REFUNDDENIALREASONS denialReason;
switch (refundToHandle.RefundCustomer.CustStatus)
{
case "C":
denialReason = REFUNDDENIALREASONS.None;
break;
case "Y":
denialReason = REFUNDDENIALREASONS.AccounthasrecentChargebackNSF;
break;
default:
denialReason = REFUNDDENIALREASONS.Fraud;
break;
}
return denialReason;
}
public static REFUNDDENIALREASONS ValidateBlocks(BatchRefund refundToHandle)
{
List<CustomerBlock> blocks = refundToHandle.RefundCustomer.Blocks;
//add new codes to block here
string[] illegalblockcodes = new string[] { "L1", "C1" };
foreach (string code in illegalblockcodes)
if (blocks.Exists(b => b.BkClassCode == code))
{
return REFUNDDENIALREASONS.Fraud;
}
return REFUNDDENIALREASONS.None;
}
}