Domanda

I'm working on designing a validator for certain objects (fields of those objects). These objects are enclosed in one, bigger object - container.

Example: Car as a container . Consists of Wheels, Engine, Body. Lets say i need to validate if wheels have correct diameter, engine has correct capacity, body has certain length etc.

Theoretically I think I should validate everything before construction of a container (car).

What is the best way to achieve this? Do I make an abstract validator class with validate() method and implement it in every enclosed class? What about the container, do I just not include it at all in the validation process? Thanks for help.

È stato utile?

Soluzione

I'd suggest you not to put the validation logic inside the classes you're going to validate.

I find it better to keep those classes as mere value objects, and create a parallel hierarchy of validators, roughly one for each entity to be validated. Alternatively, you could also create a single validator that can validate all the entities: however, this solution is less scalable and could bring you to violate the open-closed principle when you have to add a new entity (e.g. you want to deal also with the rear-view mirrors of the car).

Assuming you choose the one entity : one validator approach, the validator of the container will first validate the components inside the container and then validate if they fit together.

Please consider also the possibility of using validator frameworks such as Apache Commons Validator, that can save you from writing boilerplate code. However, since I don't know what kind of complex validation you have to perform, I don't know if it fits your needs.

Furthermore, I don't think you should be worried of validating everything before it is constructed. Just construct it and validate afterwards: then, if it violates the validation rules, you can discard it (i.e. don't persist it anywhere).

Altri suggerimenti

piggy backing off of gd1 answer, I agree. One such way would be to have a ValidatorAdapter for each of your value objects. So it would look like this:

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

Now you can have many types of validators for a single type of object, dynamic and configurable at runtime. Should you put the "valid()" method inside the classes the classes as gd1 suggest you not do, you would lose this flexibility.

You could create a ValidatablePart interface with a validate method, have all parts implement this interface, and then have the container validate all inclosed parts as they are being added to the container or perhaps when calling the the container's build or whatever method that is supposed to construct it.

Your Container class could follow the Template Method Design Pattern.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top