Класс проверки, чтобы избежать уродливых блоков if-else

Я ответил на этот вопрос о переполнении стека. Проблема в том, что в листе Excel есть 30 столбцов, и мне нужно проверить каждое из полей с другой логикой проверки. Код должен избегать множества блоков if-else. Я использовал стратегию, чтобы решить эту проблему. Я хотел бы получить обзор этого кода.

interface IValidator<T> {
  boolean validate(T field);
}

class SomeFieldOne<T> implements IValidator<T> {
  public boolean validate(T field) {
    System.out.println("SomeFieldOne validation");
    return true; // return true/false based on validation
  }
}

class SomeFieldTwo<T> implements IValidator<T> {
  public boolean validate(T field) {
    System.out.println("SomeFieldTwo validate");
    return true; // return true/false based on validation
  }
}

class Context {
  private IValidator validator;

  public Context(IValidator validator) {
    this.validator = validator;
  }

  public boolean validate(String field) {
    return this.validator.validate(field);
  }
}

public class TestValidation {
  public static void main(String[] args) {
    Context context;

    context = new Context(new SomeFieldOne());
    System.out.println(context.validate("some field one"));

    context = new Context(new SomeFieldTwo());
    System.out.println(context.validate("some field two"));

    // test other fields ....
    // .........
  }
}
11 голосов | спросил Ravi Kumar 16 62013vEurope/Moscow11bEurope/MoscowSat, 16 Nov 2013 23:48:07 +0400 2013, 23:48:07

3 ответа


10

Прежде всего, вы не используете свои дженерики здесь:

private IValidator validator;

Я бы изменил это на

private final IValidator<String> validator;

Потому что:

  1. final , потому что значение не изменяется и не должно меняться. Поле должно быть неизменным
  2. <String> для правильного использования дженериков. В противном случае вы должны получить предупреждение компилятора, говоря IValidator is a raw type. References to generic type IValidator<E> should be parameterized

Однако, я думаю, что ваш Context не очень полезен. Я не вижу причин, почему вам это нужно. Вы можете выполнить то же самое, используя:

public class TestValidation {
  public static void main(String[] args) {
    IValidator<String> context;
    context = new SomeFieldOne();
    System.out.println(context.validate("some field one"));
    context = new SomeFieldTwo();
    System.out.println(context.validate("some field two"));
    // test other fields ....
    // .........
  }
}

Это меньше кода и имеет тот же эффект. И он также выглядит лучше и улучшает читаемость, поскольку изменяющаяся стратегия теперь вызывает только один конструктор вместо двух.

Я предполагаю, что вы компилируете с помощью Java 1.6 или выше, и поэтому ваши классы, которые реализуют интерфейс IValidator, должны отмечать validate с помощью @Override для соответствия Java-кодированию конвенций. (Методы маркировки с @Override, который переопределяет методы интерфейса, вообще не поддерживались в предыдущих версиях Java)

@Override
public boolean validate(T field) {
ответил Simon Forsberg 17 72013vEurope/Moscow11bEurope/MoscowSun, 17 Nov 2013 00:09:27 +0400 2013, 00:09:27
4

Иногда использование шаблона может привести к излишней структуре. Я не говорю, что шаблон, который вы использовали здесь, не очень хорош, но мне хотелось показать, что есть еще один способ, которым вы можете передать другой блок кода, чтобы добиться проверки для разных типов полей.

interface Block<T> {
  public boolean value(T arg);
}

class FieldValidator {
  public static <T> boolean validate(T element, Block<T> block) {
    return block.value(element);
  }
}

public class UnitTest {
  public static void main(String[] args) {
    // some int field validattion
    System.out.println(FieldValidator.validate(2, new Block<Integer>() {
        public boolean value(Integer arg) {
          System.out.println("validating - " + arg);
          return true; // return true/false 
        }
      }));

    // some string field validation
    System.out.println(FieldValidator.validate("some field 1", new Block<String>() {
        public boolean value(String arg) {
          System.out.println("validating - " + arg);
          return true; // return true/false 
        }
      }));
  }
}
ответил Kinjal 17 72013vEurope/Moscow11bEurope/MoscowSun, 17 Nov 2013 01:35:04 +0400 2013, 01:35:04
1

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

на самом деле не обзор кода, но я думаю, что вопрос гарантировал ответ, который говорил о шаблонах, даже если я только плавал на поверхности

ответил Malachi 22 52013vEurope/Moscow11bEurope/MoscowFri, 22 Nov 2013 08:15:53 +0400 2013, 08:15:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132