1

I need to perform a series of validations, say ValidationA, ValidationB, ValidationC.

If any validation fails, the chain fails to validate immediately.

Each subsequent validation is performed only after the previous validation condition passes.

If a validation condition fails, I need to show a confirmation dialog to the user, e.g. "Are you sure you want to do this?" — where if the user says "Yes" then we should move on to the next validation in the chain. If the user says "No" in the confirmation dialog, then we can fail immediately.

What is a good way to implement this?

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 に答える