1

我需要执行一系列验证,比如 ValidationA、ValidationB、ValidationC。

如果任何验证失败,则链无法立即验证。

只有在前一个验证条件通过后,才会执行每个后续验证。

如果验证条件失败,我需要向用户显示一个确认对话框,例如“你确定要这样做吗?” — 如果用户说“是”,那么我们应该继续进行链中的下一个验证。如果用户在确认对话框中说“否”,那么我们可以立即失败。

什么是实现这一点的好方法?

4

3 回答 3

2

答案在 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");
}
于 2012-06-13T21:03:00.637 回答
0

像这样实现它:

(ValidationA || UserConfirmationA) && (ValidationB || UserConfirmationB) && (ValidationC || UserConfirmationC)

其中 Validation 和 UserComfirmation 是按照他们的名字所说的并返回布尔值的函数。

我假设&&并且||很懒,这在大多数语言中都是如此。

于 2012-06-13T20:50:02.093 回答
0

除了 dzendras 所说的之外,它可能有助于您查看允许您动态添加验证器的责任链模式。

于 2012-06-14T05:00:26.780 回答