使用自己的确认对话框实现验证链?

时间:2012-06-13 20:25:21

标签: algorithm design-patterns language-agnostic

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

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

每个后续验证仅在前一个验证条件通过后执行。

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

实施此方法的好方法是什么?

3 个答案:

答案 0 :(得分: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");
}

答案 1 :(得分:0)

像这样实施:

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

其中Validation和UserComfirmation是执行其名称并返回布尔值的函数。

我认为&&||是懒惰的,大多数语言都属于这种情况。

答案 2 :(得分:0)

除了dzendras所说的内容之外,您可以查看Chain of responsibility pattern,以便动态添加验证器。