Java-проектирование валидатора, иерархии классов


Я работаю над созданием валидатора для определенных объектов (полей этих объектов). Эти объекты заключены в один, более крупный объект-контейнер.

Пример: автомобиль как контейнер . Состоит из колес, двигателя, кузова. Допустим, мне нужно проверить, имеют ли колеса правильный диаметр, двигатель правильную мощность, кузов определенную длину и т. д.

Теоретически я думаю, что должен проверить все перед постройкой контейнера (автомобиля).

Чего лучше всего достичь вот это? Могу ли я создать абстрактный класс валидатора с помощью метода validate () и реализовать его в каждом вложенном классе? Как насчет контейнера, я просто не включаю его в процесс проверки? Спасибо за помощь.

3 4

3 ответа:

Я бы посоветовал вам не помещать логику проверки внутрь классов, которые вы собираетесь проверять.

Я считаю, что лучше сохранить эти классы как простые объекты значений и создать параллельную иерархию валидаторов, примерно по одному для каждой проверяемой сущности. В качестве альтернативы можно также создать единый валидатор, который может проверять все сущности: однако это решение менее масштабируемо и может привести к нарушению принципа open-closed , Когда вы придется добавить новый объект (например, вы хотите иметь дело также с зеркалами заднего вида автомобиля).

Если вы выберете подход one entity : one validator, валидатор контейнера сначала проверит компоненты внутри контейнера, а затем проверит, подходят ли они друг к другу.

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

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

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

Ваш контейнерный класс может следовать шаблонушаблона метода проектирования .

Хрюша отступает от ответа gd1, я согласен. Одним из таких способов было бы иметь ValidatorAdapter для каждого из ваших объектов value. Таким образом, это будет выглядеть следующим образом:

public class GreenCarValidator {
   public GreenCarValidator(Car car) {
      // save reference
   }

   @Override 
   public boolean isValid() {
      return car.getColor().equals("green");
   }
}

public class RedCarValidator {
   public RedCarValidator(Car car) {
      // save reference
   }

   @Override 
   public boolean isValid() {
      // you could compose more validators here for each property in the car object as needed
      return car.getColor().equals("red");
   }
}
Теперь вы можете иметь много типов валидаторов для одного типа объекта, динамических и настраиваемых во время выполнения. Если бы вы поместили метод "valid ()" в классы, которые, как предлагает gd1, вы не делаете, вы бы потеряли эту гибкость.