Я не чувствую, что этот шаблон подходит для проверки.
Если вы Google, вы найдете следующее описание вашего шаблона:
Цепочка ответственности - это шаблон поведенческого дизайна, который позволяет передавать запрашивать по цепочке потенциальных обработчиков, пока один из них не обработает запрос. Шаблон позволяет нескольким объектам обрабатывать запрос без привязки класса отправителя к конкретным классам получателей.
. Я не думаю, что это имеет место в вашем решении. Так как я чувствую, что вы не хотите обрабатывать разные проверки в разных местах ?? Я думаю, что вы используете этот шаблон как шаблон декоратора.
Вместо этого попробуйте следующее:
Как насчет того, чтобы разделить ваши объекты на следующие:
Сначала вам нужен абстрактный класс так что вы можете позже определить ваше правило валидации
public abstract class ValidationRule
{
public string Property { get; set; }
public string Error { get; set; }
public ValidationRule(string property)
{
Property = property;
Error = property + " is not valid";
}
public ValidationRule(string property, string error)
: this(property)
{
Error = error;
}
// validation method. To be implemented in derived classes
public abstract bool Validate(Validator validator);
// gets value for given business object's property using reflection
protected object GetPropertyValue(Validator validator)
{
// note: reflection is relatively slow
return validator.GetType().GetProperty(Property).GetValue(validator, null);
}
}
Затем вы можете сделать этот класс более конкретным валидатором. Может быть, законченное правило или что-то еще, что вы можете использовать повторно, например:
public class ValidateRegex : ValidationRule
{
protected string Pattern { get; set; }
public ValidateRegex(string propertyName, string pattern)
: base(propertyName)
{
Pattern = pattern;
}
public ValidateRegex(string propertyName, string errorMessage, string pattern)
: this(propertyName, pattern)
{
Error = errorMessage;
}
public override bool Validate(Validator validator)
{
return Regex.Match(GetPropertyValue(validator).ToString(), Pattern).Success;
}
}
и затем сделать из него окончательное правило
public class ValidateEmail : ValidateRegex
{
public ValidateEmail(string propertyName) :
base(propertyName, @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")
{
Error = propertyName + " is not a valid email address";
}
public ValidateEmail(string propertyName, string errorMessage) :
this(propertyName)
{
Error = errorMessage;
}
}
Валидатор может выглядеть примерно так:
public abstract class Validator
{
// list of business rules
List<ValidationRule> rules = new List<ValidationRule>();
// list of validation errors (following validation failure)
List<string> errors = new List<string>();
// gets list of validations errors
public List<string> Errors
{
get { return errors; }
}
// adds a business rule to the business object
protected void AddRule(ValidationRule rule)
{
rules.Add(rule);
}
// determines whether business rules are valid or not.
// creates a list of validation errors when appropriate
public bool IsValid()
{
bool valid = true;
errors.Clear();
foreach (var rule in rules)
{
if (!rule.Validate(this))
{
valid = false;
errors.Add(rule.Error);
}
}
return valid;
}
}
Теперь вы можете использовать валидатор следующим образом (обратите внимание, конструктор, когда вы реализуете много разных правил валидации):
public class Person : Validator
{
public Person ()
{
AddRule(new ValidateEmail("Email"));
AddRule(new ValidateId("MemberId"));
AddRule(new ValidateRequired("Email"));
AddRule(new ValidateLength("Email", 1, 100));
AddRule(new ValidateRequired("CompanyName"));
AddRule(new ValidateLength("CompanyName", 1, 40));
AddRule(new ValidateRequired("City"));
AddRule(new ValidateLength("City", 1, 15));
AddRule(new ValidateRequired("Country"));
AddRule(new ValidateLength("Country", 1, 15));
}
public int MemberId { get; set; }
public string Email { get; set; }
public string CompanyName { get; set; }
public string City { get; set; }
public string Country { get; set; }
public int NumOrders { get; set; }
public DateTime LastOrderDate { get; set; }
}
Если вы сейчас вызываете метод IsValid () все ваши правила проверки выполняются.
Я чувствую, что это то, что вы хотите. Если вы не хотите ie передавать его объекту, вы можете попытаться создать автономный валидатор и объединить валидатор с классом, в котором он вам нужен, вместо того, чтобы выводить его из него.