Шаблон проектирования для проверки ввода? - PullRequest
5 голосов
/ 14 сентября 2010

Каков наилучший способ проверки ввода?Ради аргумента, если ввод неверен, пользователю нужно сообщение, объясняющее почему.

Вот что я могу придумать.

  • Validator метод: Передать ввод в валидатор, который возвращает true, если ввод верен.В противном случае средство проверки возвращает либо false (или код ошибки) и позволяет вызывающей стороне обрабатывать неверный ввод.Или валидатор берет на себя ответственность за принятие мер.Или валидатор вызывает метод обратного вызова. Недостатки: шаги, выполняемые для проверки, могут повторяться при вызове фактического метода.

  • Передать входные данные непосредственно в метод, без проверки.Пусть метод обрабатывает недопустимые сообщения сам.Он может либо отправить сообщение об ошибке пользователю напрямую, либо использовать метод обратного вызова.После отправки сообщения метод должен вернуть или выдать исключение, чтобы прекратить обработку неверного ввода.Вызывающий класс перейдет к следующей строке ввода. Недостатки: у этого метода теперь есть побочный эффект отправки сообщения об ошибке.

Какая здесь уместная стратегия?Обратите внимание, что я не верю, что выбрасывание исключений является уместным, потому что обработка некорректного ввода является основной функцией приложения, по крайней мере, в моем случае .

Ответы [ 6 ]

2 голосов
/ 14 сентября 2010

Посмотрите на среду связывания и проверки данных Spring.Очень красиво и разработано так, чтобы его можно было использовать отдельно или как часть пользовательского интерфейса.

1 голос
/ 04 марта 2013

Хорошим решением для проверки объектов без бремени создания многих классов, реализующих интерфейс «валидатор» или использующих анонимные внутренние классы, которые нельзя использовать повторно, является использование постоянной функциональности перечисления:

Например:

public enum ObjectValidation {

BAD_DATE_FORMAT(ErrorCode.BAD_DATE_FORMAT) {

    @Override
    boolean validate(String value, List<String> acceptableValues) {
        boolean isValid = false;
        // validate the date
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        try {
            sdf.parse(value);
            isValid = true;
        } catch (ParseException ex) {

        }

        /*
         * We could use acceptableValues to validate the value against a
         * list of acceptable values
         */

        return isValid;
    }

};

private ErrorCode errorCode;

private ObjectValidation(ErrorCode ErrorCode) {
    this.errorCode = ErrorCode;
}

public ErrorCode getErrorCode() {
    return errorCode;
}

abstract boolean validate(String value, List<String> acceptableValues);

}

И сервисный метод, который использует функцию постоянной проверки, предоставляемую enum и может использоваться для нескольких проверок одного и того же поля:

public static List<ErrorCode> validate(String value, Set<ObjectValidation> objectValidators) throws Exception{
        List<ErrorCode> errorCodeList = new ArrayList<ErrorCode>();         
        for (ObjectValidation objectValidation : objectValidators) {
            if(!objectValidation.validate(value, Collections.emptyList())){
                errorCodeList.add(objectValidation.getErrorCode());
            }
        }               
    return errorCodeList;       
}
0 голосов
/ 22 сентября 2010

теперь я использую платформу валидатора Hibernate, очень простую и полезную:

Я комментирую классы тем, что мне нужно, а затем использую это:

Мой класс сущности:

public class Content {

@NotNull
private Heading heading;

@NotNull
@Length(max = 8)
private String contentType;

    // Everything else

}

Мой компонент валидатора:

@Component
public class Validator implements IValidator {
    protected static Log log = LogFactory.getLog(Validator.class);

    javax.validation.Validator validator;

    @Autowired 
    WebApplicationExceptionBuilder webApplicationExceptionBuilder;

    public void validate (Object entity) throws WebApplicationException {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
        Set<ConstraintViolation<Object>> violations = validator.validate(entity);
        if (!violations.isEmpty()) {
            webApplicationExceptionBuilder
                        .raise("some fields are missing or incorrect", 
                            violations);
        }
    }

}

Где его использовать:

public class Foo{

    @Autowired
    private IValidator validator;

    @Autowired
    private IContentService contentService;

    public void bar(Content c) throws Exception{
        validator.validate(c);
        contentService.persist(content);
    }

}
0 голосов
/ 22 сентября 2010
public interface Validator {
    /**
     * Validates a JComponent</code>.
     * @param component
     *       The component to validate.
     * @param message
     *       The message to display if the validation fails.
     * @return
     *       Returns <code>false</code> if the validation fails, and
     *       <code>true</code> otherwise.
     */
    boolean validate(JComponent component, String message);
}

У вас может быть класс AbstractValidator (Extends javax.swing.InputVerifier), который обрабатывает отображение сообщений рядом с JComponent с недопустимой записью. Взгляните на этот пример

0 голосов
/ 14 сентября 2010

Вы не должны передавать входные данные непосредственно методу (я полагаю, что под "методом" вы подразумеваете некоторую бизнес-логику), если честно, поскольку он сочетает представление и модель.Что вы должны сделать, это сделать либо контроллер с методом проверки, либо отдельным классом проверки, который будет принимать входные данные и проверять их, используя некоторые «внешние» методы.Затем в зависимости от результата контроллер / валидатор может либо вернуть ошибку валидации, либо перенаправить ввод туда, куда вы хотите.Самым большим преимуществом этого, как я уже говорил ранее, является разделение модели и представления.Модель не должна ничего знать о представлении (что, если вы хотите изменить представление? Вам придется переписать вашу модель!).Я не совсем уверен, зачем вам дублировать код проверки в бизнес-модели?Проверка и навигация должны быть тем, что делает контроллер.По крайней мере, так работает модель MVC.
Также генерировать исключения не так уж и плохо, но они должны быть добавлены в модель и зафиксированы в контроллере.Например, у вас есть система, в которой вы хотите, чтобы пользователи имели уникальные логины, пользователь вводит логин, который уже находится в БД, контроллер вызывает метод проверки, который пытается (используя модель) вставить его в БД.Если все идет хорошо, он вставляется, и контроллер может вернуть сообщение «Вы успешно вставили значение».Но если модель выдает исключение (например, ошибка нарушения уникального ограничения или что-то в этом роде), контроллер должен просто перехватить его и вернуть «этот логин уже существует в БД».Таким образом, модель ничего не знает о представлении и может использоваться повторно, и у вас нет дублирования кода.

0 голосов
/ 14 сентября 2010

Может быть, посмотрите на шаблон команды и поместите логику проверки в класс invoker.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...