我需要执行一系列验证,比如 ValidationA、ValidationB、ValidationC。
如果任何验证失败,则链无法立即验证。
只有在前一个验证条件通过后,才会执行每个后续验证。
如果验证条件失败,我需要向用户显示一个确认对话框,例如“你确定要这样做吗?” — 如果用户说“是”,那么我们应该继续进行链中的下一个验证。如果用户在确认对话框中说“否”,那么我们可以立即失败。
什么是实现这一点的好方法?
我需要执行一系列验证,比如 ValidationA、ValidationB、ValidationC。
如果任何验证失败,则链无法立即验证。
只有在前一个验证条件通过后,才会执行每个后续验证。
如果验证条件失败,我需要向用户显示一个确认对话框,例如“你确定要这样做吗?” — 如果用户说“是”,那么我们应该继续进行链中的下一个验证。如果用户在确认对话框中说“否”,那么我们可以立即失败。
什么是实现这一点的好方法?
答案在 C# 中,但我希望它很清楚。这里最重要的是原始验证与 UI 分离。OverridableValidator 是一个“UI 人”,它在构造函数中获取“逻辑人”,以及要显示给用户的消息。
interface IValidator<T>
{
bool IsValid(T subject);
}
class OverridableValidator<T> : IValidator<T>
{
readonly IValidator<T> _validator;
readonly string _confirmOverrideMessage;
public OverridableValidator(IValidator<T> validator, string confirmOverrideMessage)
{
_validator = validator;
_confirmOverrideMessage = confirmOverrideMessage;
}
public bool IsValid(T subject)
{
if (_validator.IsValid(subject))
{
return true;
}
return MessageBox.Show(_confirmOverrideMessage, "Confirmation required", MessageBoxIcon.Question, MessageBoxButtons.YesNo) == DialogResult.Yes;
}
}
class Person
{
public int Age {get;set;}
public int HeightInCentimeters {get;set;}
}
class MaturityValidator : IValidator<Person>
{
public bool IsValid(Person guy)
{
return guy.Age >= 18;
}
}
class HeightValidator : IValidator<Person>
{
public bool IsValid(Person guy)
{
return guy.HeightInCentimeters < 120;
}
}
void Main()
{
var ageValidator = new OverridableValidator<Person>(new MaturityValidator(), "Do you want to sell him cigarettes?");
var heightValidator = new OverridableValidator<Person>(new HeightValidator(), "Do you want to invite such a short person to your basketball team?");
var validatedPerson = new Person() { Age = 15, HeightInCentimeters = 140 };
var validatorsList = new[] {ageValidator, heightValidator};
foreach (var validator in validatorsList)
{
if (!validator.IsValid(validatedPerson))
{
return; //validaton failed
}
}
Console.WriteLine("This guy can smoke and play in NBA");
}
像这样实现它:
(ValidationA || UserConfirmationA) && (ValidationB || UserConfirmationB) && (ValidationC || UserConfirmationC)
其中 Validation 和 UserComfirmation 是按照他们的名字所说的并返回布尔值的函数。
我假设&&
并且||
很懒,这在大多数语言中都是如此。
除了 dzendras 所说的之外,它可能有助于您查看允许您动态添加验证器的责任链模式。