Java - 设计一个验证器,类层次结构。

9
我正在设计一个特定对象(这些对象的字段)的验证器。这些对象被包含在一个更大的容器对象中。
例如:汽车作为容器,包含轮子、发动机、车身。假设我需要验证轮子的直径是否正确,发动机的容量是否正确,车身的长度等等。
理论上,我认为应该在构建容器(汽车)之前验证一切。
那么,最好的方法是什么呢?我是否应该制作一个具有validate()方法的抽象验证器类,并在每个封闭类中实现它?至于容器,我是否只需完全排除它在验证过程中?谢谢您的帮助。

2
如果不匹配,即使是由有效的组件制成的容器也可能无效,因此您可能需要一个严格的验证方法来验证整个容器。 - Audrius Meškauskas
3个回答

4
我建议您不要将验证逻辑放在要验证的类内部。最好将这些类作为纯粹的值对象,并创建一个平行的验证器层次结构,大致上对应每个要验证的实体一个验证器。或者,您也可以创建一个可以验证所有实体的单个验证器:但是,这种解决方案的可扩展性较差,并且可能导致您在添加新实体时违反开闭原则(例如,您还想处理汽车的后视镜)。
假设您选择了“一个实体:一个验证器”的方法,则容器的验证器将首先验证容器内部的组件,然后验证它们是否合适。
请考虑使用验证器框架(如Apache Commons Validator)的可能性,它可以帮助您避免编写样板代码。但是,由于我不知道您需要执行什么样的复杂验证,因此我不知道它是否符合您的需求。
此外,我认为在构建之前无需担心验证所有内容。只需构建它并在之后进行验证:然后,如果违反验证规则,您可以将其丢弃(即不要将其保留在任何地方)。

1
将验证放在类内部会破坏SRP原则。 - PositiveGuy

2

在gd1的回答基础上,我也同意。其中一种方法是为每个值对象创建一个ValidatorAdapter。代码如下:

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");
   }
}

现在你可以为单个对象拥有多种类型的验证器,这些验证器可以在运行时进行动态配置。如果您按照gd1的建议将"valid()"方法放在类内部,您将失去这种灵活性。


1
你可以创建一个 ValidatablePart 接口,其中包含一个 validate 方法,让所有的零件都实现这个接口,然后在将它们添加到容器中时,或者在调用容器的 build 或其他构造方法时,让容器验证所有内部零件。
你的 Container 类可以遵循 模板方法设计模式

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接