Дизайн: Как получить точные журналы при регистрации из классов «высокого уровня» - PullRequest
2 голосов
/ 25 августа 2011

Вопрос

Следующий список утверждений быстро введет мой вопрос:

  • Интерфейс с именем IValidator представляет контракт для процесса проверки,
  • Некоторые классы реализуют этот интерфейс со своей собственной логикой,
  • Метод Main владеет списком IValidator и использует их все для выполнения проверки,
  • Метод Main должен регистрироватьошибка, если проверка прошла неправильно,
  • Я не хочу, чтобы классы, реализующие IValidator, вообще знали о журнале (чтобы можно было сконцентрировать все действия журнала в Main),
  • Я хочу, чтобы метод Main мог регистрировать причину ошибки валидации.

Вопрос о дизайне возникает здесь: по вашему мнению, какой лучший способ получить точный журнал о валидации (т.е.почему проверка завершилась неудачно), когда классы, реализующие проверку, не знают о журнале?

Вот код, иллюстрирующий мой вопрос:

public interface IValidator
{
    bool Validate(String toValidate);
}

public class VowelValidator : IValidator
{
    public bool Validate(string toValidate)
    {
        // .. Insert validation process here...
        return true;
    }
}

public class LenghtValidator : IValidator
{
    public bool Validate(string toValidate)
    {
        // .. Insert validation process here...
        return false;
    }
}

public class Manager
{
    public static void Main()
    {
        List<IValidator> validators = new List<IValidator>()
        {
            new VowelValidator(),
            new LenghtValidator()
        };

        foreach (var validator in validators)
        {
            if (!validator.Validate("FooBar"))
            {
                /*
                 * Handle log here.
                 * I'd like to log something like "failed because string is too long"
                 * or "failed because string does not contain vowels".
                 */
            }                    
        }
    }
}

Некоторые возможности

  • Я мог бы добавьте String GetValidationDescription() метод к IValidator и используйте его в Main, чтобы получить описание проверки, которая не прошла
    • Но это означает, что каждый раз, когда я сталкиваюсь с этой проблемой, мне придется добавлять дополнительныеМетоды только для журнала.Я не очень доволен этим.
  • Я мог бы записать фактический тип IValidator, который не удался (то есть "Validation failed on LengthValidator"), используя GetType().Затем, когда я читаю журнал, я должен помнить, что делает этот конкретный валидатор, и я могу понять, что пошло не так.
    • Это подразумевает запоминание / выяснение того, что делает валидатор: в журнале не отображается вся информация.

У вас есть другие предложения?Знаете ли вы, что такое типичная проблема?

Кристоф.

1 Ответ

2 голосов
/ 27 августа 2011

Ваш текущий дизайн для валидаторов таков, что они возвращают истину / ложь и делают другую информацию, но вы должны получить некоторые подробности о сбое, поэтому вы должны изменить интерфейс или согласиться с тем, что единственное, что вы можете регистрировать, этоValidtorXyz сказал «нет».

Поддерживать разделение интересов:

  1. Валидатор проверяет и разумно сообщает , почему проверка не пройдена
  2. Регистраторрегистрирует информацию, поэтому, если бы он знал , почему он мог бы зарегистрировать ее, в другом сценарии пользовательский интерфейс мог бы отобразить , почему

Так что ведение журнала оченьявно не ответственность валидатора.

Добавление getValidationDescription () к интерфейсу не кажется мне плохим.Для любого объекта вполне законно описывать себя - у нас везде есть методы toString ().Нельзя сказать, что это используется специально для ведения журнала.

Однако сложный валидатор, например валидатор даты, может завершиться ошибкой по нескольким причинам (например, плохо отформатированный ввод, месяц вне диапазона ...), поэтомуЯ думаю, что вам было бы лучше иметь как часть результата reasonForFailure.

Один подход: создать объект возвращаемого типа.

  class ValidationResult{
       boolean isValid;
       String validationDescription;
       String failureReason;
  }

другой подход обеспечивает возврат при сбое

   validate(String input, IOnError callThisOnError);

, где основное обеспечивает:

   class OnError implements IOnError {
         void reportError(String input, String failureReason);
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...