【问题标题】:Validating data验证数据
【发布时间】:2013-01-28 18:06:05
【问题描述】:

我有两个验证器类。假设:汽车验证器和车轮验证器,第二个包含在第一个中。

CarBodyValidator.validate(){
    WheelValidator.validate();
}

我在 CarBodyValidator、f.e EngineValidator 等中有更多验证器。validate() 应该只返回 true 或 false,并且有一次我想打印尽可能多的错误(如果某些类的验证返回 false,我想验证其他类,如果它们不相互依赖)。 现在,假设 Wheel 验证器返回了我在 CarBody 验证器中需要的有用信息。 F.e 如果车轮直径太大,那么我需要汽车验证器中的信息来验证其他内容。 我如何传递这些信息。我可以在 Wheel 验证器中创建一个存储参数的字段,但可以像这样访问它:

carBodyValidator.validate(){
    wheelValidator.validate();
    if (WheelValidator.getSmomething() == somethingElse){
      ...
    }

}

似乎是错误的(我的意思是验证器应该只验证而不做任何其他事情)。这是正确的方法还是我应该做的不同。

【问题讨论】:

  • 您是否使用特定的验证 API?
  • 不,我使用自己的验证

标签: java dependencies validation


【解决方案1】:

在这种情况下,我经常依赖观察者模式。请注意,这都是伪代码。

创建一个 ValidatorObserver 接口。

public interface ValidatorObserver{
   public void notify(int errorKey);
}

让 CarBodyValidator 实现这个接口。

public class CarBodyValidator implements ValidatorObserver{

    public void notify(int errorKey){
       switch(errorKey){
         //Evaluate cases and do something.
       }
    }
}

在 WheelValidator 上创建注册方法并设置通知

public class WheelValidator{
    private List<ValdiatorObserver> observers = new ArrayList<ValidatorObserver>();

    public void addObserver(ValidatorObserver observer){
       observers.add(observer);
    }

    public void validate(){
       //if validation fails
       for(ValidationObserver observer: observers){
          observers.notify(1); //1 is an error code
       }
    }
}

您需要在代码中的某处注册观察者

CarBodyValiator cbValidator = new CarBodyValidator();
WheelValidator wheelValidator = new WheelValidator();
wheelValidator.addObserver(cbValidator);

【讨论】:

    【解决方案2】:

    有多种方法可以做到这一点。一如你所说。让 validate() 返回一个布尔值并保留一组在验证期间发生的错误。如果需要,您可以稍后询问这些错误。

    更优雅的解决方案可能是让 validate() 方法返回一个名为 ValidationResults 的特定类的实例。此类可以包含验证状态和错误集。

    第三种选择可能是在 validate() 中抛出异常。虽然有人反对这种方法,因为不建议使用异常来决定应用程序的执行流程,但我发现它在某些情况下很有用。

    希望对你有帮助,

    【讨论】:

    • 抛出异常会做 OP 想要避免的事情:当单个验证失败时中断验证过程。
    【解决方案3】:

    这对于Visitor pattern 来说是一个很好的应用程序。

    这意味着您有一个传递给每个验证器的对象(访问者)。验证器向访问者报告他们的错误消息和/或将其传递给执行相同操作的其他子验证器。

    访问者存储所有传递给它的错误消息。之后,您可以阅读访问者收集的错误消息并以您认为合适的任何方式处理它们。

    【讨论】:

      【解决方案4】:

      如果对象无效,您可以抛出异常,而不是返回指示验证是否通过的布尔值:

      public void validateCar(Car car) throws ValidationException {
          if (car.getEngine() == null) throw new ValidationException("Engine is null", "engine");
      }
      

      ValidationException 包含错误字段,然后可以在另一个验证器中重用。

      但在我看来,当您知道对象无效时调用另一个验证器似乎有点错误。或许您应该合并这两个验证器并使其返回无效字段列表?

      【讨论】:

        猜你喜欢
        • 2014-10-04
        • 1970-01-01
        • 2017-02-04
        • 2021-02-03
        • 1970-01-01
        • 2017-07-20
        • 2022-01-15
        • 2010-11-15
        相关资源
        最近更新 更多